Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Firebird-Restore: auch ohne exclusiven Zugriff möglich? (https://www.delphipraxis.net/212126-firebird-restore-auch-ohne-exclusiven-zugriff-moeglich.html)

hoika 22. Dez 2022 08:01

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

Firebird-Restore: auch ohne exclusiven Zugriff möglich?
 
Hallo,
so wie ich es verstanden habe, will gbak beim Restore exclusiven Zugriff auf die DB. (=?)
Mit -R (replace) kann ich ja immerhin schon DBs ersetzen, auch wenn Sie im Netz liegen.

Lässt sich der exclusive Zugriff irgendwie umgehen?

PS:
Ich weiß, dass es gefährlich ist ...

Lemmy 22. Dez 2022 13:41

AW: Firebird-Restore: auch ohne exclusiven Zugriff möglich?
 
nicht dass ich wüsste... Aber vielleicht erklärst Du ein paar Takte was das Problem ist bzw. für was das wichtig ist.
Möglich wäre: Restore mit einem anderen Namen, dann wäre die Downtime relativ kurz.... (2 Dateien umbenennen)

Grüße

hoika 22. Dez 2022 15:27

AW: Firebird-Restore: auch ohne exclusiven Zugriff möglich?
 
Hallo Lemmy,
DB (+Firebird) ist auf dem Server (Zimmer abgeschlossen),
einer ist angemeldet auf dem Rechner im Zimmer.

Restore wäre notwendig, geht nicht, weil DB offen ...

Delphi.Narium 22. Dez 2022 16:38

AW: Firebird-Restore: auch ohne exclusiven Zugriff möglich?
 
Monitoringtabellen von FireBird benutzen?

In MON$STATEMENTS stehen die laufenden SQL-Statements, in MON$ATTACHMENTS stehen die offenen Verbindungen.

Mit
SQL-Code:
DELETE FROM MON$STATEMENTS WHERE MON$ATTACHMENT_ID = :ATTACHMENT_ID
beendest Du ein laufendes Statement, mit
SQL-Code:
DELETE FROM MON$ATTACHMENTS WHERE MON$ATTACHMENT_ID = :ATTACHMENT_ID
beendest Du eine aktive Datenbankverbindung (jeweils ohne Rücksicht auf Verluste, ohne Nachfrage, ...)

Sinngemäß ungetestet hingedaddelt:
Delphi-Quellcode:
// Statement für das Löschen einer bestimmten Verbingung erstellen
qryExec.SQL.Text := 'DELETE FROM MON$ATTACHMENTS WHERE MON$ATTACHMENT_ID = :ATTACHMENT_ID; commit;';
// Alle Attachment_IDs zu offenen Verbindungen ermitteln,
// sofern Du dich als letzter User an der DB angemeldet hast,
// wird Deine eigene Verbindung zuletzt beendet.
// Oder halt die eigene ATTACHMENT_ID vorher ermitteln und per Where-Bedingung ausklammern.
qry.SQL.Text := 'select MON$ATTACHMENT_ID as ATTACHMENT_ID from MON$ATTACHMENTS order by MON$ATTACHMENT_ID';
qry.Open;
while not qry.EoF do begin
  qryExec.SQL.ParamByName('ATTACHMENT_ID').AsInteger := qry.FieldByName('ATTACHMENT_ID').AsInteger;
  qryExec.ExecSQL;
  qry.Next;
end;
qry.Close;
Damit sollten dann alle Datenbankverbindungen weg sein, einschließlich Deiner eigenen Verbindung.

Eventuell geht es ja auch mit
Delphi-Quellcode:
qryExec.SQL.Add('execute block as');
qryExec.SQL.Add('begin');
qryExec.SQL.Add(' DELETE FROM MON$ATTACHMENTS;');
qryExec.SQL.Add(' commit;');
qryExec.SQL.Add('end');
qryExec.SQL.ExecSQL;
Da damit dann auch die eigene Verbindung weg ist, könnte ein Try-Execpt drumrum nicht schaden ;-)

Und: Diese Lösung ist (wenn sie so funktioniert) garantiert äußerst grenzwertig:!:

lxo 22. Dez 2022 20:05

AW: Firebird-Restore: auch ohne exclusiven Zugriff möglich?
 
Du könntest auch einfach die Datenbank herunterfahren und damit alle Verbindungen trennen.

https://firebirdsql.org/rlsnotesh/rn...util-gfix.html

himitsu 22. Dez 2022 21:04

AW: Firebird-Restore: auch ohne exclusiven Zugriff möglich?
 
Ja, natürlich kannst du zuerst mal alle offenen Connections trennen.
es sollte ein SQL geben, welche dir alle liefert, und dann damit das Disconnect.
https://stackoverflow.com/questions/...ip-in-firebird
https://www.firebirdfaq.org/faq10/
https://www.firebirdfaq.org/faq64/
Bei Google suchenfirebird colse all active connections


Den DB-Inhalt als SQL-Text (CreateTable und Inserts und eventuell DeleteOhneWhere, falls Tabellen schon da sind) exportieren
(dafür eventuell es erstmal auf einer temporäten lokalen DB importieren/restoren)
und dann einfach das/die SQL-Scripte in der eigentlichen DM


Eventuell auch noch die Trigger und Checks disablen, damit nichts verändert wird und die Reihenfolge der Tabellen egal ist.

IBExpert 23. Dez 2022 06:36

AW: Firebird-Restore: auch ohne exclusiven Zugriff möglich?
 
exklusiv ist beim restore immer erforderlich, weil u.a. auch die Systemtabellen neu erzeugt werden und beim restore am ende erst indizes erzeugt werden und trigger und foreign keys aktiviert werden und das darf nicht durch irgendwelche operationen vorher mit ungültigen daten das verhindern.

Früher (interbase <= 5.5) konnte man während des Restores schon an die Datenbank, war aber eine blöde idee, damit haben kunden dann zum Teil ihre db so zerstört, das eine reparatur ziemlich aufwändig bis unmöglich war.

Wichtig ist auch das beim Restore die Transaktionscounter resettet werden müssen und das kann man nicht mit altdaten mischen.

Was aber geht wenn es beim restore nicht um das Transaktionslimit geht (als next transaction in der datenbankstatistik von fb<=2.5 in der nähe von 2 Milliarden ist):
Nutze ein geeignetes Tool und mache einfach eine abgleich zwischen der restorten datenbank und deiner produktionsdatenbank
mir fällt da gerade das hier ein :-) https://www.ibexpert.net/ibe/pmwiki....leDataComparer
das geht damit auch nur für von dir ausgewählte Tabellen und kann wenn Primärschlüssel oder unique constraints super gut auch insert/update/delete automatisch erkennen und teile der tabellen sogar durch extra where bedingungen in der ibeblock funktion https://www.ibexpert.net/ibe/index.p..._CompareTables nutzen

fazit aber: mit gbak zwingend exklusiv, während des restores kommst du gar nicht erst an die db mit einer zweiten connection, weil der restore im shutdown single user mode läuft, daher ist der hinweis auf die Mon$ Tabellen nicht hilfreich.

wenn es nur darum geht, das aktive Connections der restore verhinden, machst du am besten vorher ein shutdown mit gfix oder https://www.ibexpert.net/ibe/pmwiki....utdownDatabase, mit full shutdown werden alle user rausgeschmissen ob die wollen oder nicht und können sich auch nicht neu anmelden. danach geht das restore mit replace ziemlich sicher ohne probleme, ist aber wie oben geschildert bis zur fertigstellung auch im shutdown single user mode und keiner kann währenddessen an die daten.

Delphi.Narium 23. Dez 2022 10:01

AW: Firebird-Restore: auch ohne exclusiven Zugriff möglich?
 
Zitat:

Zitat von IBExpert (Beitrag 1516595)
daher ist der hinweis auf die Mon$ Tabellen nicht hilfreich.

Wieso nicht?

Wenn ich gbak starte und 'ne Meldung bekomme, dass dies nicht möglich ist, weil nicht exklusiv zugegriffen werden kann, so kann ich in dieser Situation doch in die Mon$-Tabellen schauen und prüfen, ob noch Datenbankverbindungen bestehen.

Wenn ja, kann ich auch sehen, von welchem Client auf die Datenbank zugegriffen wird und statt die Verbindungen zu trennen, könnte ich auch den / die entsprechenden User bitten, ihre Datenbankverbindung zu beenden, um dann weiter arbeiten zu können.

Natürlich: Wenn (aus welchem Grund auch immer) kein Zugriff auf die Mon$-Tabellen möglich ist, hab' ich noch ein anderes Problem, als nur noch laufenden SQL-Statements oder einfach nicht beendete Datenbankverbindungen.

Aber bei nicht möglichem Exklusivzugriff für gbak, halte ich es durchaus für einen zielführenden Versuch, zuerst mal in die Mon$-Tabellen zu schauen, um zu ermitteln, was da ggfls. den Exklusivzugriff verhindert. Es könnte ja durchaus die Möglichkeit bestehen, dass da noch sinnvolle Arbeiten auf der Datenbank ausgeführt werden und ein hartes Beenden der SQL-Statements bzw. der Datenbankverbindungen ggfls. eher geschäftsschädigende Auswirkungen nach sich ziehen könnte.

himitsu 23. Dez 2022 11:54

AW: Firebird-Restore: auch ohne exclusiven Zugriff möglich?
 
Ja klar, was spricht denn dagegen statt die Verbindungen blind hart abzuschießen, vorher nachzusehen und den Clienten eventuell gezielt zu sagen, dass "sie" zu machen sollen?
(und wer dann noch nicht gehört hat, oder hängen geblieben ist, der wird dann eben hart serverseitig disconnected)


Wir nutzen bei uns die DB-Notivications im PostgreSQL,
da gibt es also in allen Clients etwas, was auf eine Shutdown-Benachrichtigung hört,
dann einen Dialog anzeigt, dass in x Sekunden/Minuten runtergefahren oder neugestrtet wird.
Nutzer haben noch eine Chance fertig zu machen und die Clienten beenden sich selbstständig, ohne hart die Verbindung und damit eventuell ungespeicherte Daten zu verlieren.
(wir nutzen das aber vorwiegend für Programm- und Datebankupdates)


OK, bei einem Restore ist eh alles egal, ob noch was ungespeichert war ... am Ende ist ja alles weg/geändert/überschrieben, worauf die Änderungen in den Clients basierten.
Und selbst wenn vor dem Ende noch gespeichert würde, dann würde es hier ja eh anschließend gelöscht/überschrieben.

IBExpert 23. Dez 2022 23:34

AW: Firebird-Restore: auch ohne exclusiven Zugriff möglich?
 
ja, wenn man connections noch zuende arbeiten lassen will kann man die natürlich in der dann noch nicht
shutdown db in den monitor tables nachschauen, wer da noch was macht. Du kannst die da auch mit einem delete
auf genau dieser tabelle auch noch selektiv rauswerfen, das funktioniert auch (leider nur) fast immer.

Wenn du dann aber das backup startest und das ohne shutdown machst kann sich weiterhin jeder an der db anmelden
und alles was nach dem start vom backup noch von irgendeinem client in die db geschrieben wurde, ist dann nach
dem restore nicht mehr da, weil beim restore nur der zustand zurückgeschrieben wird, der beim start vom backup
committed war, weil nur das im Backup file ist.

Wenn also ganz klar backup mit anschliessendem restore angesagt ist (und nur dann brauch ich
das exklusiv), dann hast du sonst eine nette lücke im konzept, die man mit dem zwangsshutdown
single user mode vor dem backup schon mal verhindern kann.

Die mon$attachments ist eine super hilfsmittel im täglichen betrieb und mit deren id lassen sich auch in
mon$transactions problemlos langlaufende transaktion erkennen und anschliessend selektiv auf der mon$attachments
rauswerfen.

Das ist aber eher für daily business ohne schon eingeplanten restore hilfreich. Und beim Original
Posting hab ich das so verstanden, das das überschreiben der db mit restore auf jeden fall die
Grundlage für seine Frage war.

Und irgendwelche events die dem client dann noch x minuten geben, in denen der dann seine Arbeit abschliessen kann,
wird man eh brauchen. Wenn man bei größeren firmen versucht, die in mon$attachments erkannten user nacheinander
anzurufen, wird das endlos sein, weil ohne harten shutdown sich die clients schon wieder anmelden, weil die
meinen, das wenn die software läuft das auch erlaubt ist damit zu arbeiten.

ob ein shutdown nun in deiner exe implementiert ist und anhand irgendwelche Attribute in der db erkennt, das
es sich abmelden soll, ist dafür schon akzeptiert, aber irgendwelche dienste die man noch beenden müsste oder
webserver interessiert das nicht unbedingt, es sei denn die kennen und akzeptieren die gleichen gründe offline
zu bleiben. Über datenbanktrigger lässt sich das auch variabel blockieren, aber shutdown ist vergleichsweise
einfach.


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:25 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