Delphi Firedac резервное копирование базы данных Firebird в локальный файл - PullRequest
0 голосов
/ 09 декабря 2018

Можно ли использовать TFDFBNBackup и TFDFBNRestore для создания и восстановления резервных копий с / на удаленный сервер из локальных файлов?

Я знаю, что это можно сделать с помощью командной строки локального диспетчера службинструмент, подобный gbak, также позволяет это, но я не хочу использовать эти инструменты в моем новом приложении Firemonkey (Windows, OSX, Linux).Я хочу полностью скомпилировать функциональность в свое приложение, и у меня будет доступ к серверу только на основе подключения Firebird, без общего файлового ресурса.

1 Ответ

0 голосов
/ 12 декабря 2018

Благодаря предложению Ариоха я смог решить эту проблему, и она работает хорошо.Я использовал сервис 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;
...