Recent

Author Topic: Firebird Database backup  (Read 9357 times)

TRNelson

  • Jr. Member
  • **
  • Posts: 64
Firebird Database backup
« on: February 22, 2016, 11:59:15 pm »
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

  • Hero Member
  • *****
  • Posts: 753
Re: Firebird Database backup
« Reply #1 on: February 23, 2016, 04:55:16 am »
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]
  1. procedure TForm1.BackupDatabase();
  2.     const READ_BYTES = 2048;
  3.     var
  4.     aProcess: TProcess; //TProcess is crossplatform is best way
  5.     MemStream: TMemoryStream;
  6.     NumBytes: LongInt;
  7.     BytesRead: LongInt;
  8.     Lines: TStringList;
  9.   begin
  10.    // A temp Memorystream is used to buffer the output
  11.    MemStream := TMemoryStream.Create;
  12.    Lines :=TStringList.Create;
  13.    BytesRead := 0;
  14.  
  15.      aProcess := TProcess.Create(nil);
  16.      aProcess.Executable := 'C:\Program Files (x86)\Firebird\Firebird_2_5\bin\gbak.exe';
  17.      aProcess.Parameters.Add('-backup');
  18.      aProcess.Parameters.Add('-user');
  19.      aProcess.Parameters.Add('SYSDBA');
  20.      aProcess.PArameters.Add('-password');
  21.      aProcess.Parameters.Add('masterkey');
  22.      aProcess.Parameters.Add('F:\lazarus_1_6RC1\projets\Test_Firebird\mushrooms.fdb');
  23.      aProcess.Parameters.Add('F:\lazarus_1_6RC1\projets\Test_Firebird\mushrooms.fbk');
  24.      aprocess.ShowWindow := swoHIDE;
  25.      AProcess.Options := AProcess.Options + [poUsePipes,poStderrToOutPut];
  26.      Memo1.lines.Clear;
  27.      Memo1.lines.Add('Backup in progress ...');
  28.      aProcess.Execute;
  29.      while aProcess.Running do
  30.      begin
  31.        // make sure we have room
  32.        MemStream.SetSize(BytesRead + READ_BYTES);
  33.        // try reading it
  34.        NumBytes := aProcess.Output.Read((MemStream.Memory + BytesRead)^, READ_BYTES);
  35.        if NumBytes > 0 // All read() calls will block, except the final one.
  36.           then Inc(BytesRead, NumBytes)
  37.        else
  38.           BREAK // Program has finished execution.
  39.      end;
  40.      MemStream.SetSize(BytesRead);
  41.      Lines.LoadFromStream(MemStream);
  42.      Memo1.lines.AddStrings(Lines);
  43.      Memo1.lines.Add('Backup terminated');
  44.      aProcess.Free;
  45.      Lines.Free;
  46.      MemStream.Free;
  47.   end;

Friendly, J.P
Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

dogriz

  • Full Member
  • ***
  • Posts: 105
    • Tech blog - Delphi, Lazarus, Firebird, Windows, Linux, Android...
Re: Firebird Database backup
« Reply #2 on: February 23, 2016, 08:24:09 am »
Very good example. You can add:
Code: [Select]
aProcess.Parameters.Add('-v'); for verbose output.
FPC 3.0.4
Lazarus 2.0.2
Debian x86_64, arm

TRNelson

  • Jr. Member
  • **
  • Posts: 64
Re: Firebird Database backup
« Reply #3 on: February 23, 2016, 03:55:50 pm »
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

  • Hero Member
  • *****
  • Posts: 3842
Re: Firebird Database backup
« Reply #4 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.

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.
« Last Edit: February 23, 2016, 05:02:04 pm by rvk »

JD

  • Hero Member
  • *****
  • Posts: 1758
Re: Firebird Database backup
« Reply #5 on: February 23, 2016, 06:29:21 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.

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
« Last Edit: February 23, 2016, 06:47:39 pm by JD »
Windows (10, 7) - Lazarus 2.0RC3/FPC 3.2, NewPascal, Delphi

Indy 10.6 series; mORMot; Zeos 7.2.1; SQLite, Firebird, PostgreSQL & MariaDB; VirtualTreeView 5.5.3 R1

rvk

  • Hero Member
  • *****
  • Posts: 3842
Re: Firebird Database backup
« Reply #6 on: February 23, 2016, 07:16:10 pm »
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.
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]
  1. uses FBAdmin;
  2.  
  3. procedure TForm1.logadm(Sender: TObject; msg: string; IBAdminAction: string);
  4. begin
  5.   Memo1.Lines.add(IBAdminAction + ' : ' + msg);
  6. end;
  7.  
  8. procedure Backup(Database, Backupfile: string);
  9. var
  10.   Admin: TFBAdmin;
  11. begin
  12.   Admin := TFBAdmin.Create(nil);
  13.   try
  14.     Admin.UseExceptions := True;
  15.     Admin.Host := '192.168.1.66';
  16.     Admin.Protocol := IBSPTCPIP;
  17.     Admin.User := 'SYSDBA';
  18.     Admin.Password := 'masterkey';
  19.     Admin.Port := 3050;            //change if not using the default port
  20.     Admin.Connect;
  21.     Admin.OnOutput := @Form1.logadm;
  22.     Admin.Backup(Database, Backupfile, [IBBkpVerbose]);
  23.   finally
  24.     Admin.Free; //disconnects automatically
  25.   end;
  26. end;
  27.  
  28. procedure Restore(Database, Backupfile: string);
  29. var
  30.   Admin: TFBAdmin;
  31. begin
  32.   Admin := TFBAdmin.Create(nil);
  33.   try
  34.     Admin.UseExceptions := True;
  35.     Admin.Host := '192.168.1.66';
  36.     Admin.Protocol := IBSPTCPIP;
  37.     Admin.User := 'SYSDBA';
  38.     Admin.Password := 'masterkey';
  39.     Admin.Port := 3050;                   //change if not using the default port
  40.     Admin.Connect;
  41.     Admin.OnOutput := @Form1.logadm;
  42.     Admin.Restore(Database, Backupfile, [IBResVerbose, IBResReplace]);
  43.   finally
  44.     Admin.Free; //disconnects automatically
  45.   end;
  46. end;
  47.  
  48. procedure TForm1.btBackupClick(Sender: TObject);
  49. begin
  50.   Backup('c:\data\demo.fdb', 'c:\temp\demo.fbk');
  51. end;
  52.  
  53. procedure TForm1.btRestoreClick(Sender: TObject);
  54. begin
  55.   Restore('c:\data\demo_restored.fdb', 'c:\temp\demo.fbk');
  56. 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.
« Last Edit: February 23, 2016, 07:18:35 pm by rvk »

rvk

  • Hero Member
  • *****
  • Posts: 3842
Re: Firebird Database backup
« Reply #7 on: February 23, 2016, 07:26:51 pm »
I added the example to the wiki-page (my first wiki-edit :D):
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

  • Hero Member
  • *****
  • Posts: 1758
Re: Firebird Database backup
« Reply #8 on: February 24, 2016, 06:57:17 am »
I added the example to the wiki-page (my first wiki-edit :D):
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
Windows (10, 7) - Lazarus 2.0RC3/FPC 3.2, NewPascal, Delphi

Indy 10.6 series; mORMot; Zeos 7.2.1; SQLite, Firebird, PostgreSQL & MariaDB; VirtualTreeView 5.5.3 R1

TRNelson

  • Jr. Member
  • **
  • Posts: 64
Re: Firebird Database backup
« Reply #9 on: February 25, 2016, 12:14:59 am »
%) 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

  • Jr. Member
  • **
  • Posts: 64
Re: Firebird Database backup
« Reply #10 on: February 25, 2016, 12:18:40 am »
I added the example to the wiki-page (my first wiki-edit :D):
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

  • Jr. Member
  • **
  • Posts: 72
Re: Firebird Database backup
« Reply #11 on: June 21, 2016, 02:48:02 pm »
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.
« Last Edit: June 21, 2016, 02:52:23 pm by dony »

rvk

  • Hero Member
  • *****
  • Posts: 3842
Re: Firebird Database backup
« Reply #12 on: June 21, 2016, 02:49:48 pm »
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 the data as well?
In the example on the Wiki the data is definitely backuped too.

donnie

  • Jr. Member
  • **
  • Posts: 72
Re: Firebird Database backup
« Reply #13 on: June 21, 2016, 02:58:51 pm »
I just haven't use the
Code: Pascal  [Select]
  1. Admin.OnOutput := @Form1.logadm;
which is for the memo messages. I also used the local host
Code: Pascal  [Select]
  1. Admin.Host := '127.0.0.1';
The result was to take an empty database.
« Last Edit: June 21, 2016, 03:01:10 pm by dony »

rvk

  • Hero Member
  • *****
  • Posts: 3842
Re: Firebird Database backup
« Reply #14 on: June 21, 2016, 03:06:20 pm »
I just haven't use the
Code: Pascal  [Select]
  1. 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?