Delphi Firedac备份Firebird数据库到本地文件
Delphi Firedac backup Firebird database to local file
是否可以使用 TFDFBNBackup
和 TFDFBNRestore
从本地文件创建和恢复备份 from/to 远程服务器?
我知道这可以通过 gbak 等本地服务管理器命令行工具来完成,但我不想在我的新 Firemonkey 应用程序中使用这些工具(Windows,OSX, Linux).我想将功能完全编译到我的应用程序中,我只能在 Firebird 连接的基础上访问服务器,不能共享文件。
感谢 Arioch 的建议,我可以解决它并且效果很好。我使用 gbak 服务来压缩备份文件。也应该与 nbackup 风格一起使用。
请在下面找到一些示例代码 ,没有任何错误处理作为概念证明 。由于备份只有在绝对可靠的情况下才有意义,因此在为生产目的实施此概念时,必须进行复杂的错误检测和处理。
此外,必须在服务器上修改 firebird.conf 以允许外部文件访问数据库所在文件夹中的文件。我在 Windows 中创建了一些数据库的备份,并对传输到本地机器的文件进行了二进制比较。
在示例中,我提供了一个标签和一个进度条。备份组件应设置为详细以显示进度,尽管这会减慢服务器上的备份速度我希望能够向用户提供反馈。
procedure TForm1.Button1Click(Sender: TObject);
var
count: int64;
fs: TFileStream;
x: integer;
procedure dropBackupTable;
begin
with FDQuery do
begin
sql.text := 'execute block as ' + 'begin ' +
'if (exists(select 1 from rdb$relations where rdb$relation_name=''BACKUP'')) then ' +
'execute statement ''drop table backup'';' + 'end';
execute;
end;
end;
begin
lbl.text := 'Online backup on server...';
dropBackupTable;
pb.Value := 2;
pb.Max := 2000;
with FDIbBackup do
begin
host := '192.168.2.14';
database := 'r:\databases\office.fdb';
port := 1216;
UserName := 'SYSDBA';
Password := '???????';
BackupFiles.Clear;
BackupFiles.add('r:\databases\back.fbk');
Backup;
end;
lbl.text := 'Copying backup file...';
with FDQuery do
begin
sql.text := 'create table backup external ''r:\databases\back.fbk'' (x integer)';
execute;
sql.text := 'select count(*) from backup';
open;
count := fields[0].AsInteger;
close;
pb.Max := count div 1024;
pb.Value := 0;
sql.text := 'select * from backup';
open;
fs := TFileStream.create('d:\temp\local.fbk', fmCreate, (fmShareDenyRead or fmShareDenyNone));
count := 0;
while not eof do
begin
inc(count);
x := fields[0].AsInteger;
fs.write(x, sizeOf(x));
if count > 1023 then
begin
pb.Value := pb.Value + 1;
application.processmessages;
count := 0;
end;
next;
end;
close;
fs.free;
pb.Value := 0;
end;
dropBackupTable;
lbl.text := 'Ready.';
end;
procedure TForm1.FBBackProgress(ASender: TFDPhysDriverService; const AMessage: string);
begin
if pb.Value = pb.Max then
pb.Value := 2
else
pb.Value := pb.Value + 1;
application.processmessages;
end;
是否可以使用 TFDFBNBackup
和 TFDFBNRestore
从本地文件创建和恢复备份 from/to 远程服务器?
我知道这可以通过 gbak 等本地服务管理器命令行工具来完成,但我不想在我的新 Firemonkey 应用程序中使用这些工具(Windows,OSX, Linux).我想将功能完全编译到我的应用程序中,我只能在 Firebird 连接的基础上访问服务器,不能共享文件。
感谢 Arioch 的建议,我可以解决它并且效果很好。我使用 gbak 服务来压缩备份文件。也应该与 nbackup 风格一起使用。
请在下面找到一些示例代码 ,没有任何错误处理作为概念证明 。由于备份只有在绝对可靠的情况下才有意义,因此在为生产目的实施此概念时,必须进行复杂的错误检测和处理。
此外,必须在服务器上修改 firebird.conf 以允许外部文件访问数据库所在文件夹中的文件。我在 Windows 中创建了一些数据库的备份,并对传输到本地机器的文件进行了二进制比较。
在示例中,我提供了一个标签和一个进度条。备份组件应设置为详细以显示进度,尽管这会减慢服务器上的备份速度我希望能够向用户提供反馈。
procedure TForm1.Button1Click(Sender: TObject);
var
count: int64;
fs: TFileStream;
x: integer;
procedure dropBackupTable;
begin
with FDQuery do
begin
sql.text := 'execute block as ' + 'begin ' +
'if (exists(select 1 from rdb$relations where rdb$relation_name=''BACKUP'')) then ' +
'execute statement ''drop table backup'';' + 'end';
execute;
end;
end;
begin
lbl.text := 'Online backup on server...';
dropBackupTable;
pb.Value := 2;
pb.Max := 2000;
with FDIbBackup do
begin
host := '192.168.2.14';
database := 'r:\databases\office.fdb';
port := 1216;
UserName := 'SYSDBA';
Password := '???????';
BackupFiles.Clear;
BackupFiles.add('r:\databases\back.fbk');
Backup;
end;
lbl.text := 'Copying backup file...';
with FDQuery do
begin
sql.text := 'create table backup external ''r:\databases\back.fbk'' (x integer)';
execute;
sql.text := 'select count(*) from backup';
open;
count := fields[0].AsInteger;
close;
pb.Max := count div 1024;
pb.Value := 0;
sql.text := 'select * from backup';
open;
fs := TFileStream.create('d:\temp\local.fbk', fmCreate, (fmShareDenyRead or fmShareDenyNone));
count := 0;
while not eof do
begin
inc(count);
x := fields[0].AsInteger;
fs.write(x, sizeOf(x));
if count > 1023 then
begin
pb.Value := pb.Value + 1;
application.processmessages;
count := 0;
end;
next;
end;
close;
fs.free;
pb.Value := 0;
end;
dropBackupTable;
lbl.text := 'Ready.';
end;
procedure TForm1.FBBackProgress(ASender: TFDPhysDriverService; const AMessage: string);
begin
if pb.Value = pb.Max then
pb.Value := 2
else
pb.Value := pb.Value + 1;
application.processmessages;
end;