Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi [FibPlus] Restore (https://www.delphipraxis.net/179663-%5Bfibplus%5D-restore.html)

MrSpock 23. Mär 2014 13:38

Datenbank: Firebird • Version: 2.5 • Zugriff über: FibPlus

[FibPlus] Restore
 
Hallo,

zu diesem Thema gibt es zwar schon einen Tread, aber der ist so alt, dass ich die Frage nocheinmal neu aufbringe.

Ich nutze folgenden Code, um ein Backup einzuspielen:

Delphi-Quellcode:
procedure TMainForm.Backupeinspielen1Click(Sender: TObject);
var
  server: string;
  posi: Integer;
begin
   server := DatMod.DM.DBPost32.DatabaseName;
   posi := Pos(':',server);
   server := Copy(DatMod.DM.DBPost32.DatabaseName, 1, posi -1);
   pFIBRS.ServerName := server;
   pFIBRS.DatabaseName.Clear;

   pFIBRS.DatabaseName.Add(Copy(DatMod.DM.DBPost32.DatabaseName, posi+1,
                        length(DatMod.DM.DBPost32.DatabaseName)-posi));
   pFIBRS.BackupFile.Clear;
   if iniSavePath = '' then
      OpenDlg.InitialDir := ExtractFileDir(pFIBBU.DatabaseName)
   else
      OpenDlg.InitialDir := iniSavePath;
   // OpenDlg.FileName := 'Post32Backup_'+DateToStr(Today);
   if OpenDlg.Execute then
   begin
      // ShowMessage(SaveDlg.FileName);
      try
         pFIBRS.BackupFile.Add(OpenDlg.FileName);
         pFIBRS.Params.Clear;
         pFIBRS.Params.Add('password=masterkey');
         pFIBRS.Params.Add('user_name=SYSDBA');
         DatMod.DM.DBPost32.Close; // << hier schließe ich die einzige Verbindung zur Datenbank
         pFIBRS.Attach;
         SB.Panels[0].Text := 'Bitte warten, Backup wird zurückgespielt.';
         SB.Update;

         pFIBRS.ServiceStart;
         while pFIBRS.IsServiceRunning do
         begin
            Application.ProcessMessages;
            Sleep(1000);
         end;

          SB.Panels[0].Text := '';
          SB.Update;
          // ShowMessage('Backup erstellt.');
          ShowMessage('Backup eingespielt. Programm neu starten!');
      except on E: Exception do
         begin
            ShowMessage('Backup konnte nicht eingespielet werden.'+#10#13+
                     E.Message);
            SB.Panels[0].Text := 'Fehler beim Backup einspielen. Programm neu starten';
         end;
      end;
      Close;
   end;

end;
An der markierten Stelle schließe ich die Datenbank, bevor ich mit dem Restore beginne.
Anschließend kommt die Fehlermeldung, dass die DB nicht gedropt werden kann, weil sie möglicherweise in Benutzung ist.

---------------------------
...
---------------------------
Backup konnte nicht eingespielet werden.

MainForm.pFIBRS:
Unsuccessful execution caused by system error that does not preclude successful execution of subsequent statements.
Could not drop database G:\Daten\DBs\POST32.FDB (database might be in use).

---------------------------

Öffne ich dann IBExpert und versuche es dort, bekomme ich dieselbe Meldung.

Bestätige ich die Fehlermeldung in meinem Programm, schließt es sich. Dann kann ich über IBExpert ein Restore vornehmen.
Das heißt wohl, dass mein Programm beim Start des Restore noch immer die DB nutzt. Wie kann ich die Datenbank so schließen, dass ein Restore möglich ist?
OK
---------------------------

MrSpock 23. Mär 2014 15:39

AW: [FibPlus] Restore
 
Habe jetzt festgestellt, dass trotz Schließens der Datenbank noch ein Eintrag in der System-Tabelle

Delphi-Quellcode:
DatMod.DM.DBPost32.CloseDataSets;
DatMod.DM.pFIBQryDelMon.ExecQuery;
DatMod.DM.TAMain.Commit;
DatMod.DM.DBPost32.ForceCloseTransactions;
DatMod.DM.DBPost32.Close;
in der Query pFIBQryDelMon steht:

Zitat:

DELETE FROM MON$ATTACHMENTS
damit lösche ich auch den Eintrag, der von der Anwendung ja noch aktiv ist. Das ist ja wie sägen an dem Ast, auf dem man sitzt.

Danach lässt die das Restore dann ausführen. Aber es muss doch auch "eleganter" gehen, oder?

Lemmy 23. Mär 2014 18:05

AW: [FibPlus] Restore
 
Nur weil du die Verbindung zur DB schließt, heißt es ja nicht, dass der FB-Server das dann auch gleich macht und dann spielt auch noch das Betriebssystem mit rein (caching,...).

Nach dem Close also auf alle Fälle ein application.Processmessages machen - das Close zudem so weit wie möglich nach oben schieben - das ganze Vorbereitungszeug vor dem Dlg.execute - das kannst Du auch machen nachdem der Dialog ausgeführt wurde UND die Datenbankverbindung geschlossen wurde.

Ach ja: Und sicher sein, dass das wirklich die einzigste DB-Verbindung in der Anwendung ist :-)

Grüße

MrSpock 23. Mär 2014 19:31

AW: [FibPlus] Restore
 
Mit einem Application.ProzessMessages funktioniert es tatsächlich auch ohne das Löschen der Daten in der Systemtabelle :-)


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:49 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz