Firebird Database backup lazarus / 16-Databases ---------------------------------------------------------------------- TRNelson · 2016-02-22 22:59 I would like to use the Firebird utility gbak (probably gfix as well) to backup and restore a database from within an application.  Any messages would be put in a memo field.  The backups would be stored on the server.  Rather than re-invent the wheel, I wonder if someone out there has done this wouldn't mind sharing some code or insight into this. ---------------------------------------------------------------------- Jurassic Pork · 2016-02-23 03:55 hello, you can try to use Tprocess (from process unit) to run external program gbak and redirect output std and err to memo (using a tmemorystream). Something like that : Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TForm1.BackupDatabase();    const READ_BYTES = 2048;    var    aProcess: TProcess; //TProcess is crossplatform is best way    MemStream: TMemoryStream;    NumBytes: LongInt;    BytesRead: LongInt;    Lines: TStringList;  begin   // A temp Memorystream is used to buffer the output   MemStream := TMemoryStream.Create;   Lines :=TStringList.Create;   BytesRead := 0;      aProcess := TProcess.Create(nil);     aProcess.Executable := 'C:\Program Files (x86)\Firebird\Firebird_2_5\bin\gbak.exe';     aProcess.Parameters.Add('-backup');     aProcess.Parameters.Add('-user');     aProcess.Parameters.Add('SYSDBA');     aProcess.PArameters.Add('-password');     aProcess.Parameters.Add('masterkey');     aProcess.Parameters.Add('F: \lazarus_1_6RC1\projets\Test_Firebird\mushrooms.fdb');     aProcess.Pa rameters.Add('F:\lazarus_1_6RC1\projets\Test_Firebird\mushrooms.fbk');    aprocess.ShowWindow := swoHIDE;     AProcess.Options := AProcess.Options + [poUsePipes,poStderrToOutPut];     Memo1.lines.Clear;     Memo1.lines.Add('Backup in progress ...');     aProcess.Execute;     while aProcess.Running do     begin       // make sure we have room       MemStream.SetSize(BytesRead + READ_BYTES);       // try reading it       NumBytes := aProcess.Output.Read((MemStream.Memory + BytesRead)^, READ_BYTES);     if NumBytes > 0 // All read() calls will block, except the final one.          then Inc(BytesRead, NumBytes)       else          BREAK // Program has finished execution.     end;     MemStream.SetSize(BytesRead);     Lines.LoadFromStream(MemStream);   Memo1.lines.AddStrings(Lines);     Memo1.lines.Add('Backup terminated');     aProcess.Free;     Lines.Free;     MemStream.Free;  end; Friendly, J.P ---------------------------------------------------------------------- dogriz · 2016-02-23 07:24 Very good example. You can add: Code: [Select]aProcess.Parameters.Add('-v'); for verbose output. ---------------------------------------------------------------------- TRNelson · 2016-02-23 14:55 Thanks guys!  This is very helpful.  Similar to what I was working on.  I was having a trying a time to get my head around the redirects. Now I need to figure out how to invoke this remotely. ---------------------------------------------------------------------- rvk · 2016-02-23 16:00 Is there anything wrong with using TFBAdmin.Backup() and TFBAdmin.Restore() instead of an external gbak?? With TFBAdmin you can backup and restore databases using the internal services from Firebird. You can even do it with the embedded Firebird. Also... gbak is not always installed. You need to install the development tools to be abble to use gbak. And finally... If you are using the gbak.exe, don't hardcode "Program Files (x86)" and "Firebird_2_5". For me, I always install the 64bit server, even if my program is 32bit, and that code will fail. (I'm not sure why you installed the 32bit server on a 64bit machine ??? because that's absolutely not necessary) Look in the registry where the correct Firebird files are located. (look in HKEY_LOCAL_MACHINE\SOFTWARE\Firebird Project\Firebird Server\Instances with the 64bit KEY_WOW64_64KEY on for 32bit programs) So it's much easier to use the internal services which TFBAdmin does. ---------------------------------------------------------------------- JD · 2016-02-23 17:29 Quote from: rvk on February 23, 2016, 05:00:28 pmIs there anything wrong with using TFBAdmin.Backup() and TFBAdmin.Restore() instead of an external gbak?? With TFBAdmin you can backup and restore databases using the internal services from Firebird. You can even do it with the embedded Firebird. So it's much easier to use the internal services which TFBAdmin does. I agree with you but do you happen to have an example of the usage of TFBAdmin.Restore? I can see the TFBAdmin.Backup example here http://wiki.freepascal.org/TFBAdmin BUT I can't find an example of TFBAdmin.Restore. I'll really appreciate it. JD ---------------------------------------------------------------------- rvk · 2016-02-23 18:16 Quote from: JD on February 23, 2016, 06:29:21 pmI agree with you but do you happen to have an example of the usage of TFBAdmin.Restore? I can see the TFBAdmin.Backup example here http://wiki.freepascal.org/TFBAdmin BUT I can't find an example of TFBAdmin.Restore. I'll really appreciate it. That example uses the BackupMultiFile, which I never use. I just use the Backup() and Restore() and zip and upload it to a secure location. The actual code is just as simple as in that example (see below). The only down- (or up)side of using the backup/restore services of Firebird is that the backup is made server-side (unless you're already running this on the server). So you can run the backup from a client. But that client might not have access to the physical backup-file (depending on the network access-rights), which off course could also be a good thing. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i uses FBAdmin; procedure TForm1.logadm(Sender: TObject; msg: string; IBAdminAction: string);begin  Memo1.Lines.add(IBAdminAction + ' : ' + msg);end; procedure Backup(Database, Backupfile: string);var  Admin: TFBAdmin;begin  Admin := TFBAdmin.Create(nil);  try    Admin.UseExceptions := True;    Admin.Host := '192.168.1.66';    Admin.Protocol := IBSPTCPIP;    Admin.User := 'SYSDBA';    Admin.Password := 'masterkey';    Admin.Port := 3050;            //change if not using the default port    Admin.Connect;    Admin.OnOutput := @Form1.logadm;    Admin.Backup(Database, Backupfile, [IBBkpVerbose]);  finally    Admin.Free; //disconnects automatically  end;end; procedure Restore(Database, Backupfile: string);var  Admin: TFBAdmin;begin  Admin := TFBAdmin.Create(nil);  try    Admin.UseExceptions := True;    Admin.Host := '192.168.1.66';    Admin.Protocol := IBSPTCPIP;    Admin.User := 'SYSDBA';    Admin.Password := 'masterkey';    Admin.Port := 3050;                 //change if not using the default port    Admin.Connect;    Admin.OnOutput := @Form1.logadm;    Admin.Restore(Database, Backupfile, [IBResVerbose, IBResReplace]);  finally    Admin.Free; //disconnects automatically  end;end; procedure TForm1.btBackupClick(Sender: TObject);begin  Backup('c:\data\demo.fdb', 'c:\temp\demo.fbk');end; procedure TForm1.btRestoreClick(Sender: TObject);begin  Restore('c:\data\demo_restored.fdb', 'c:\temp\demo.fbk');end; You could also use an already existing connection for backup. And there is no need to terminate any connection because backup can be done during operation of all clients. And if you do want to use BackupMultiFile() to backup to multiple files you can just use RestoreMultiFile(), with the same string-list containing the backup-files, to restore the database. ---------------------------------------------------------------------- rvk · 2016-02-23 18:26 I added the example to the wiki-page (my first wiki-edit ): http://wiki.freepascal.org/TFBAdmin#Example The backup-part might seem a bit double but it shows the single-file backup while the original example was for multi-file backup. ---------------------------------------------------------------------- JD · 2016-02-24 05:57 Quote from: rvk on February 23, 2016, 07:26:51 pmI added the example to the wiki-page (my first wiki-edit ): http://wiki.freepascal.org/TFBAdmin#Example The backup-part might seem a bit double but it shows the single-file backup while the original example was for multi-file backup. Many, many thanks to you. I only do server-side backup & restore anyway so your example is fine for me. JD ---------------------------------------------------------------------- TRNelson · 2016-02-24 23:14 Quote from: rvk on February 23, 2016, 05:00:28 pm Is there anything wrong with using TFBAdmin.Backup() and TFBAdmin.Restore() instead of an external gbak?? With TFBAdmin you can backup and restore databases using the internal services from Firebird. You can even do it with the embedded Firebird. There is nothing wrong with using any of those mentioned.  I was simply unaware of them.  It looks like a much better sol;ution for all the reasons noted.  Thanks! ---------------------------------------------------------------------- TRNelson · 2016-02-24 23:18 Quote from: rvk on February 23, 2016, 07:26:51 pmI added the example to the wiki-page (my first wiki-edit ): http://wiki.freepascal.org/TFBAdmin#Example The backup-part might seem a bit double but it shows the single-file backup while the original example was for multi-file backup. Excellent.  Great example.  This is exactly what I was looking for. ---------------------------------------------------------------------- donnie · 2016-06-21 12:48 Hi there, Nice example! As I tried it, I saw that this is only for the database structure and not for the data of the tables. How can I backup and restore the data of the database as well? Thank you in advance. ---------------------------------------------------------------------- rvk · 2016-06-21 12:49 Quote from: dony on June 21, 2016, 02:48:02 pmAs I tried it, I saw that this is only for the database structure and not for the data of the tables. How can I backup the data as well? In the example on the Wiki the data is definitely backuped too. ---------------------------------------------------------------------- donnie · 2016-06-21 12:58 I just haven't use the Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Admin.OnOutput := @Form1.logadm;which is for the memo messages. I also used the local host Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Admin.Host := '127.0.0.1'; The result was to take an empty database. ---------------------------------------------------------------------- rvk · 2016-06-21 13:06 Quote from: dony on June 21, 2016, 02:58:51 pmI just haven't use the Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Admin.OnOutput := @Form1.logadm;which is for the memo messages. Maybe you should log the messages. Maybe there is a corruption in the database and data isn't exported (which would give a message in the log). Does backuping up with the gbak utility work? ---------------------------------------------------------------------- donnie · 2016-06-21 13:37 Finally did it!!! There was a problem with the roles. Indeed the messages helped me to change them and everything completed. Many many thanks again.