Agendador de Backup para FireBird/InterBase

Um dos problemas que muitos enfrentam atualmente no uso do FireBird/InterBase é uma ferramenta de Backup que seja automatizada, possibilitando múltiplos backup’s sem a intervenção do usuário, e partindo da dificuldade de encontrar uma ferramenta que atendesse as minhas necessidades desenvolvi um sistema chamado GRMonitor, de propriedade da Grafcenter Informática LTDA, e decidi compartilhar meus conhecimentos aplicados no mesmo com a comunidade.

O Sistema que demonstrado aqui é um exemplo de como se começar a fazer um projeto de automação de Backup, sendo possível adicionar funcionalidades para torna-lo adequado a cada caso, até mesmo compactação de arquivo e cópia para outros locais. Foi usado para desenvolvimento desse exemplo o Delphi 6.0/IBX, mas poderão ser utilizadas outras versões do mesmo, desde que se adapte aos recursos disponíveis.

O Sistema de Backup está dividido em dois módulos:

  1. Configurador; e
  2. Monitor.
  3. O Configurador gera os parâmetros para que se defina a sistemática de Backup da base de dados, como:

    • Localização do Banco de Dados a ser backupeado;
    • Dias e horários para execução do Backup;
    • Diretório para armazenamento dos arquivos de Backup; e

O Monitor executa os Backup’s nos dias e horários programados pelo Configurador.

Sem prolongar muito vamos ao que interessa...

 

O Configurador:

A primeira coisa a se fazer é abrir o Delphi, criar um novo Projeto e salvar, nesse projeto são usados:

 

São utilizados também outros componentes como disposto na figura:

No evento OnCreate do FPrincipal temos:

 
procedure TFPrincipal.FormCreate(Sender: TObject);
var
  reg: TRegistry;
  i: integer;
  
begin
  reg := TRegistry.Create;
  try
    reg.RootKey := HKEY_LOCAL_MACHINE;
    if reg.OpenKey('\Software\FireBackup', false) then
      begin
        eBase.Text := reg.ReadString('Base');
        eDirBackup.Text := reg.ReadString('BackupDir');
        for i := Low(Dia) to High(Dia) do
          begin
            try
              clbSemana.Checked[i] := reg.ReadBool(Dia[i]);
            except
              
            end;
          end;
        if reg.OpenKey('\Software\FireBackup\Horarios', false) then
          begin
            try
              for i := 0 to (clbHorarios.Items.Count - 1) do
                begin
                  try
                    clbHorarios.Checked[i] := reg.ReadBool(FormatFloat('00', i) + ':00');
                  except

                  end;
                end;
            except
            end;
          end;
      end;
  finally
    reg.CloseKey;
    reg.Free;
  end;
end;

O Evento OnCreate foi utilizado para fazer a carga dos dados já configurados no Registro do Windows, podendo ser utilizados outros métodos para gravação, como Banco de Dados, arquivos, etc.

Explicando as linhas acima:

No nosso formulário temos os botões de Ok que faz a gravação dos dados no registro, e o de Cancelar para fechar o Configurador.

No botão de Ok, inserimos o código abaixo no evento OnClick:

procedure TFPrincipal.sbOkClick(Sender: TObject);
var
  reg: TRegistry;
  i: integer;
begin
  reg := TRegistry.Create;
  try
    reg.RootKey := HKEY_LOCAL_MACHINE;
    if reg.OpenKey('\Software\FireBackup', true) then
      begin
        reg.WriteString('Base', eBase.Text);
        reg.WriteString('BackupDir', eDirBackup.Text);

        for i := Low(Dia) to High(Dia) do reg.WriteBool(Dia[i], clbSemana.Checked[i]);

        if reg.OpenKey('\Software\FireBackup\Horarios', true) then
          begin
            for i := 0 to (clbHorarios.Items.Count - 1) do
              begin
                try
                  reg.WriteBool(FormatFloat('00', i) + ':00', clbHorarios.Checked[i]);
                except

                end;
              end;
          end;
      end;
  finally
    reg.CloseKey;
    reg.Free;
  end;
  Close;
end;

Nas linhas acima é feita uma varredura pelos itens dos dias da semana e dos horários e fazendo a gravação dos mesmos no registro.

O botão Cancelar somente faz o fechamento da aplicação.

No botão sbBuscaBase(o que tem o desenho de uma lupa), são inseridas as seguintes linhas de código no evento OnClick:

procedure TFPrincipal.sbBuscaBaseClick(Sender: TObject);
begin
  with TOpenDialog.Create(Self) do
    begin
      Filter := 'FireBird/InterBase Database(*.gdb)|*.gdb';
      if Execute then eBase.Text := FileName;
    end;
end;

O botão BuscaBase, cria uma janela para buscar a base de dados que se deseja que o Backup seja efetuado.

 

O Monitor

Procedemos da mesma forma da criação do Configurador, e usamos as definições:

Neste projeto são usados os componentes a seguir:

No Evento OnShow do FPrincipal, usamos:

procedure TFPrincipal.FormCreate(Sender: TObject);
var
  reg: TRegistry;
  DiaBackup: Boolean;
  i: integer;

begin
  reg := TRegistry.Create;
  try
    reg.RootKey := HKEY_LOCAL_MACHINE;
    if not reg.OpenKey('\Software\FireBackup', false) then
      begin
        MessageBox(Handle, PChar('Não existem configurações definidas!'), PChar('Erro'), MB_OK or MB_ICONWARNING);
        PostMessage(Application.Handle, WM_CLOSE, 0, 0);
      end
    else
      begin
        try
          DiaBackup := reg.ReadBool(Dia[DayOfWeek(date)]);
        except
          DiaBackup := false;
        end;
        if not DiaBackup or not reg.OpenKey('\Software\FireBackup\Horarios', false) then AddStatusLine('Não existe Backup agendado para hoje...', clMaroon, 12)
        else
          begin
            AddStatusLine(Format('FireBackup inicializado às %s horas', [FormatDateTime('hh:nn:ss', now)]), clNavy, 12);
            for i := low(Horarios) to high(Horarios) do
              begin
                Horarios[i].Hora := I;
                Horarios[i].Agendado := reg.ReadBool(FormatFloat('00', i) + ':00');
              end;
            Timer.Enabled := true;
          end;
      end;
  finally
    reg.CloseKey;
  end;
end;

Neste evento do Form, fazemos a verificação se existem configurações, caso hão existam é postada uma mensagem à aplicação que se feche após o processo de inicialização.

No caso da existência de configurações, é preenchido o vetor de horários agendados, o mesmo é definido da seguinte forma:

  THorario = packed record
    Hora: TTime;
    Feito: Boolean;
    Agendado: Boolean;
  end;

  private
    Horarios: array[0..23] of THorario;


No componente Backup são definidas as configurações:

Options: [NoGarbageCollection];
Params
user_name=SYSDBA
password=masterkey

 

No evento OnTimer do Timer, temos a codificação responsável pela execução do Backup:

procedure TFPrincipal.TimerTimer(Sender: TObject);
var
  i: integer;
begin
  for i := low(Horarios) to High(Horarios) do
    begin
      if (Horarios[i].Agendado) and (not Horarios[i].Feito) and (Horarios[i].Hora = HourOf(now)) then
        begin
          Timer.Enabled := false;
          Horarios[i].Feito := DoBackup;
          Timer.Enabled := true;
          Break;
        end;
    end;
end;

A cada ciclo do Timer, é verificado no vetor de horários, se há algum agendamento para àquela hora, caso haja é executado o Backup(DoBackup) e ajustado os parâmetros no vetor, para que não haja substituição do Backup Atual.

A função DoBackup, disparada no evento OnTimer do Timer, é responsável pelo acionamento do serviço de backup do FireBird/InterBase:

function TFPrincipal.DoBackup: Boolean;
var
  reg: TRegistry;
begin
  Result := true;
  reg := TRegistry.Create;
  try
    reg.RootKey := HKEY_LOCAL_MACHINE;
    if reg.OpenKey('\Software\FireBackup', false) then
      begin
        try
          ForceDirectories(reg.ReadString('BackupDir'));
          Backup.DatabaseName := reg.ReadString('Base');
          Backup.BackupFile.Clear;
          Backup.BackupFile.Add(ChangeFileExt(reg.ReadString('BackupDir') + '\' + FormatDateTime('yyyymmddnnhh', now), '.gbk'));
          Backup.Active := true;
          AddStatusLine(Format('Backup Iniciado às %s horas', [FormatDateTime('hh:nn:ss', now)]), clGreen);
          AddStatusLine('Não serão apresentadas linhas de Status, o modo Verbose está desligado!', clNavy);
          Backup.ServiceStart;
          Backup.Active := false;
        except
          Result := false;
        end;
      end;
  finally
    reg.CloseKey;
    reg.Free;
  end;
end;
 

A procedure AddStatusLine é usada para adicionar linhas ao componente seStatus, tendo a sua condificação definida a seguir:

procedure TFPrincipal.AddStatusLine(S: string; Cor: TColor; Tamanho: byte);
begin
  reStatus.SelAttributes.Color := Cor;
  reStatus.SelAttributes.Size := Tamanho;
  reStatus.Lines.Add(S);
end;

Em ambos projetos, há uma constante chamada Dia, essa constante armazena um array de string’s onde estão armazenados os dias da semana, sendo definida assim:

const
  Dia: array[1..7]    of string = ('Domingo',    'Segunda', 'Terça',    'Quarta',    'Quinta',    'Sexta', 'Sábado');

Obs.: As nomenclaturas, identação dos fontes, figuras, componentes que foram podem ser facilmente substituídos para maior adaptação do Projeto para as necessidades de cada um.

Click aqui para baixar o código dos programas.

Autor : Julio Cesar (julio_gyn@yahoo.com.br)
Analista/Programador
Grafcenter Informática LTDA.
Publicado no site Interbase-BR


Interbase-BR - Copyright (c) 2000 by Carlos H. Cantu - Voltar para a página principal