【问题标题】:Delphi Firedac backup Firebird database to local fileDelphi Firedac 备份 Firebird 数据库到本地文件
【发布时间】:2019-05-10 14:44:43
【问题描述】:

是否可以使用TFDFBNBackupTFDFBNRestore 从本地文件创建和恢复远程服务器的备份?

我知道这可以通过本地服务管理器命令行工具来完成,例如 gbak 也允许这样做,但我不想在我的新 Firemonkey 应用程序(Windows、OSX、Linux)中使用这些工具。我想将功能完全编译到我的应用程序中,我只能通过 Firebird 连接访问服务器,没有文件共享。

【问题讨论】:

  • 你知道TFDFBNBackup是nbackup,它和gbak完全不同吗?无论如何,Embarcadero documentation 表明这是不可能的。 Firebird 本身确实支持远程 nbackup。
  • 是的,我知道。通常 gbak 后面的 ser 服务也只将文件写入服务器本地,但客户端上的 gbak 以某种方式完成了它。如果有一种无需调用命令行实用程序的方法,我也会使用更简单的 FBIBBAckup。
  • 对不起,我不知道德尔福。我知道Firebird本身支持这个,我不知道是否有支持这个的Delphi组件。
  • 谢谢。我还想在远程机器上创建一个服务,定期检查备份文件的存在,压缩它并创建一个二级数​​据库,其中包含一个包含备份的 blob 字段。听起来很奇怪,但也许可行。
  • gbak 在客户端可以通过两种方式工作:原始方式只是向服务器发出标准的 SQL 命令,在客户端接收标准查询结果集,并将它们保存到 FBK 文件中。在 FB 2.5 的一些后续版本中引入的新方法是允许在服务器上运行 gbak 服务,并通过服务 API 将 FBK 文件流式传输到客户端 - 这个新功能在 FB 2.5.x relnotes 中宣布。但是对于 nbackup 则不同: 1) nbackup 在 SQL 数据级别上不起作用,它不了解 SQL,它镜像页面 - FDB 文件块。它在低级工作。 2) 没有关于的消息

标签: delphi firebird firedac firebird-3.0


【解决方案1】:

感谢 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;

【讨论】:

  • 现在,这 过度设计 :-) gbak(nBackup 的一部分)可以通过服务 API 在网络上本地传递备份数据。请参阅我向 Mark 提到的 Firebird 文件。不需要使用 gbak 的 ET 变通办法 - 您可以按原样在远程存储数据中使用备份服务
  • 另外,“因为备份只有在绝对可靠的情况下才有意义”——IB/FB 有一个细节是“不可恢复的备份”,因为它们的灵活性允许更改数据结构和对去,可能会产生逻辑上禁止的状态。因此,对于 gbak 来说,立即恢复数据是一个很好的做法(尽管它正在处理中)——如果需要,只需检查 FBK 在实践中是否可用。甚至用新创建的文件替换工作数据库文件。
  • ` 备份组件应设置为详细以显示进度,尽管这会减慢服务器上的备份速度`您确定吗?我相信它会减慢客户端的速度,因为TMemo(实际上是底层 WinGDI 对象)在许多小的添加工作负载中性能低下。如果您将日志缓存到TList<string> 并且每 1/3 秒仅将其转储到备忘录一次,并且在工作结束后 - 那么我认为它应该仍然很快
  • 感谢 cmets。 Delphi 组件似乎不支持远程的东西。但我会做一些额外的研究。
  • 为了可靠性:我使用特定的 firebird 版本打包我的应用程序,因此我确信使用 gbak 创建的备份是兼容的。通常我确实让备份恢复到数据库副本,因此验证备份文件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多