Seite 1 von 2

automatisches Backup und Zwischenspeichern (flush) bei externer hsqldb

Verfasst: Fr 8. Mär 2024, 12:52
von Aubergino
Moin in die Runde,
bisher habe ich mein Projekt als interne hsqldb geführt.
Darin habe ich aus dem Handbuch (Kap. 9) die automatische Sicherungskopie und das Zwischenspeichern übernommen, beides klappt prima. Das Zwischenspeichern habe ich an alle Ereignisse gekoppelt, mit denen im Formular der aktuelle Datensatz verlassen wird.

Nun habe ich, wieder nach Handbuch (Anhang) auf externe DB umgestellt, auch das hat letztlich gut geklappt.
Aber:
Damit ist die Sicherungskopie und das Zwischenspeichern in der bisherigen Form wohl sinnlos geworden, weil ja sowohl das LO-Backup als auch die Flush-Prozedur leider, aber logischer Weise nicht die externen Daten, sondern die .odb-Datei sichern bzw. schreiben.

Für die Sicherungskopie wäre es vermutlich am einfachsten, mit der filecopy-Prozedur zu arbeiten? Und damit die .data - Datei zu kopieren, am besten wieder mit rolierenden Versionsnummern.
Dazu wäre meine Frage, ob ich irgendwie, ähnlich wie die ThisComponent.URL auch den Pfad zu den externen Daten auslesen könnte?

Für die Flush-Funktion habe ich als einigermaßen erfolgreicher Copy- und- Paster keine eigene Lösungsidee...

Hintergrund der Umstellung auf externe Daten ist, dass ich gerne mal daheim am Programm arbeiten will, während in dem kleinen Museum, für das die Datenbank den Bestand führen soll, auch jemand anderes an den Daten arbeiten könnte. Das soll ja nicht verloren gehen, wenn ich mit einer geänderten .odb daherkomme...

Re: automatisches Backup und Zwischenspeichern (flush) bei externer hsqldb

Verfasst: Fr 8. Mär 2024, 15:50
von RobertG
Ich arbeite hier viel mit externen Firebird-Datenbanken. Der flush-Befehl funktioniert da genauso. Schau doch einmal nach, ob sich bei Dir mit einer externen HSQLDB bei einem flush die database-Datei ändert.

Für die interne Firebird-Datei habe ich das Makro aus dem Handbuch entsprechend erweitert:

Code: Alles auswählen

	stUrl_Start = ThisDatabaseDocument.DataSource.URL	'Pfad zur Datenbank'
	IF InStr(stUrl_Start, "file:/") THEN
		ar() = Split(stUrl_Start, "file:/")
		stUrl_Start = "file:/" & ar(1)
		ar1() = Split(stUrl_Start,"/")
		stTitel = ar1(UBound(ar1))
		stUrl_Ziel = BackupTarget(stTitel,inMax)
		REM Der Pfad für die Zieldatei wird festgelegt und das Dokument zur Zieldatei hin kopiert.
		FileCopy(stUrl_Start,stUrl_Ziel)	
	END IF
Dabei habe ich die Funktion "BackupTarget" als separates Element genommen, weil ich sowohl die Firebird-Datei als auch die Base-Datei nacheinander mit dem gleichen Verfahren sichere.
Du müsstest natürlich jetzt natürlich den entsprechenden Pfad zur Datenbankdatei bereinigen. Was vor "file:/" steht wird durch die Prozedur raus genommen. Wenn aber Parameter zusätzlich angegeben werden oder das Ganze, wie bei der HSQLDB in einem Unterverzeichnis liegt, dann muss da entsprechend eine Erweiterung eingebaut werden.

Re: automatisches Backup und Zwischenspeichern (flush) bei externer hsqldb

Verfasst: Fr 8. Mär 2024, 21:42
von Aubergino
Danke für die Tipps.

Zum automatischen Backup: die Kernantwort auf meine Frage war ja:
-> stUrl_Start = ThisDatabaseDocument.DataSource.URL
als Zugriff auf die Adresse der externen Datenbank.
Damit habe ich nun eine funktionierende Backuplösung für die externen HSQLDB-Daten:

Code: Alles auswählen

SUB Datenbankbackup
DIM oPath AS OBJECT
DIM sTitel AS STRING
DIM stUrl_Ziel AS STRING
DIM stUrl_Start AS STRING
DIM i AS INTEGER
DIM k AS INTEGER
DIM inMax AS INTEGER
DIM ar() AS STRING

  stUrl_Start = ThisDatabaseDocument.DataSource.URL
  IF InStr(stUrl_Start, "file:") THEN
	ar() = Split(stUrl_Start, "file:")
	stUrl_Start = "file:/" & ar(1)
  END IF
  IF InStr(stUrl_Start, ";") THEN
	ar() = Split(stUrl_Start,";")
	stUrl_Start = ar(0)
  END IF
  stUrl_Start = stUrl_Start + ".data"
  msgbox stUrl_Start
  REM Sicherungspfad 1 ist der externe Datenpfad
  FOR i = 1 TO inMax + 1
    IF NOT FileExists(LEFT(stUrl_Start,LEN(stUrl_Start) - 5,0) & "_" & i & ".data") THEN
      IF i > inMax THEN
        FOR k = inMax - 1 TO 1 STEP -1
          IF FileDateTime(LEFT(stUrl_Start,LEN(stUrl_Start) - 5,0) & "_" & k & ".data") _
          <= FileDateTime(LEFT(stUrl_Start,LEN(tsUrl_Start) - 5,0) & "_" & k+1 & ".data") THEN
            IF k = 1 THEN
              i = k
              EXIT FOR
            END IF
          ELSE
            i = k + 1
            EXIT FOR
          END IF
        NEXT
      END IF
      EXIT FOR
    END IF
  NEXT
  stUrl_Ziel = LEFT(stUrl_Start,LEN(stUrl_Start) - 5,0) & "_" & i & ".data"
  FileCopy(stUrl_Start,stUrl_Ziel1)
    
  REM Sicherungspfad 2 ist der vorgegebenen Pfad aus den Libre-Office-Einstellungen
  oPath = createUnoService("com.sun.star.util.PathSettings")
  ar()=Split(stUrl_Ziel,"/")
  stUrl_Ziel = oPath.Backup & "/" & ar(UBOUND(ar))
  On error Resume Next
  FileCopy(stUrl_Start,stUrl_Ziel2)
END SUB
Ich erstelle damit die rolierend nummerierten Sicherungskopien der Datenbankname.data - Datei. Eine Kopie schreibe ich in den Pfad der externen Datenbank. Und dann noch eine zweite mit gleichem Namen in den in LO hinterlegten Sicherungspfad. Damit kriege ich die auf zwei Festplatten.

Hinweise/Verbesserungen werden gern genommen...

Re: automatisches Backup und Zwischenspeichern (flush) bei externer hsqldb

Verfasst: Fr 8. Mär 2024, 21:52
von Aubergino
Weiter nicht gelöst ist die Sache mit dem Zwischenspeichern.
Ich habe beobachtet, ob der Flush-Aufruf (ausgelöst nach Änderungen der Daten im Formular beim Datensatzwechsel) die .odb-Dateien im Programmverzeichnis oder die .data-Dateien im externen Datenverzeichnis aktualisiert, anhand des Datums der letzten Änderung.

Das hatte bei der internen HSQLDB geklappt - da wurde die "Datenbankname.odb" beim Flush aktualisiert.

Bei der externen HSQLDB wird leider weiterhin die "Datenbankname.odb", also das Programm, aktualisiert, aber nicht die externen Daten. Dsgl. beim "Speichern" im Datenbankfenster. Erst beim vollständigen Schließen der Datenbank ändert sich das Datum der .data-Datei.

Was nun?? Danke für Tipps...

Re: automatisches Backup und Zwischenspeichern (flush) bei externer hsqldb

Verfasst: Sa 9. Mär 2024, 11:47
von RobertG
Das mit der HSQLDB extern wird dann vermutlich nur etwas direkt beim Aufruf. Du kannst also kein sinnvolles Backup bei geöffneter Datei machen. Dann liegt der gesamte Inhalt noch im flüchtigen Speicher.

Das ist bei Firebird anders. Da sehe ich jede kleine Änderung sofort in der Datei. Da habe ich auch vorher die Datensicherheit getestet: Base mit externe Firebird-Datei, dann Base und LO gekillt (also wie bei einem Absturz von LO) und die zuletzt eingegebenen Daten waren erhalten. Das ist natürlich nicht bei internen Datenbanken der Fall, weil die ja nicht mehr gepackt werden können. Aber wie die Sicherheit der HSQLDB gewährleistet ist, wenn da das System einfriert weiß ich nicht. Schlimmstenfalls sind alle Daten seit dem Öffnen der *.odb-Datei dann weg.

Re: automatisches Backup und Zwischenspeichern (flush) bei externer hsqldb

Verfasst: Sa 9. Mär 2024, 13:58
von Freischreiber
RobertG hat geschrieben:
Sa 9. Mär 2024, 11:47
Aber wie die Sicherheit der HSQLDB gewährleistet ist, wenn da das System einfriert weiß ich nicht. Schlimmstenfalls sind alle Daten seit dem Öffnen der *.odb-Datei dann weg.

Um Himmels Willen, nein. Während der Eingabe werden laufend Dateien geschrieben, je nachdem, ob es sich um memory- oder cached tables handelt, eine log-Datei, eine data-Datei und eine script-Datei. Dieses Schreiben passiert standardmäßig innerhalb von 500ms nach der Eingabe. Die Einstellung ist SET FILES WRITE DELAY.

Enthält die Datenbank nur memory tables, gibt es z. B. gar keine data-Datei.

Bei einem Crash bleiben diese ständig aktualisierten Dateien stehen und werden beim nächsten Start mit eingelesen. Enthält die Datenbank cached tables, bleibt eine data-Datei stehen und wird erst dann mit der script-Datei zusammengeführt, wenn man direkt "shutdown script" ausführt. Das macht das System irgendwann wohl auch automatisch.

Zur Sicherung genügt es also, wenn die script-, die data- und die log-Datei gesichert werden, daraus sollte die Datenbank beim nächsten Start den Zustand vor dem Crash wieder herstellen können.

Gruß
Freischreiber

Re: automatisches Backup und Zwischenspeichern (flush) bei externer hsqldb

Verfasst: Sa 9. Mär 2024, 14:15
von Freischreiber
Hier mal ein Zitat aus dem HSQL-Handbuch dazu:
Types of catalog data

• mem: stored entirely in RAM - without any persistence beyond the JVM process's life
• file: stored in file system
• res: stored in a Java resource, such as a Jar and always read-only
All-in-memory mem: catalogs can be used for test data or as sophisticated caches for an application. These databases
do not have any files.
A file: catalog consists of between 2 to 6 files, all named the same but with different extensions, located in the same
directory. For example, the database named "testdb" consists of the following files:
• testdb.properties
• testdb.script
• testdb.log
• testdb.data
• testdb.backup
• testdb.lobs

The properties file contains a few settings about the database. The script file contains the definition of tables and
other database objects, plus the data for memory tables. The log file contains recent changes to the database. The
data file contains the data for cached tables and the backup file is used to revert to the last known consistent state
of the data file. All these files are essential and should never be deleted. For some catalogs, the testdb.data and
testdb.backup files will not be present. In addition to those files, a HyperSQL database may link to any formatted
text files, such as CSV lists, anywhere on the disk.

While the "testdb" catalog is open, a testdb.log file is used to write the changes made to data. This file is removed
at a normal SHUTDOWN. Otherwise (with abnormal shutdown) this file is used at the next startup to redo the changes.
A testdb.lck file is also used to record the fact that the database is open. This is deleted at a normal SHUTDOWN.
Eine separate Backup-Datei gibt es wohl bei neueren HSQL-Versionen nicht mehr, dort ist SET FILES BACKUP INCREMENT TRUE eingeschaltet.

Re: automatisches Backup und Zwischenspeichern (flush) bei externer hsqldb

Verfasst: Sa 9. Mär 2024, 16:02
von RobertG
Hallo Freischreiber,

wie erklärst Du Dir dann aber die Beobachtung von Aubergino:
Bei der externen HSQLDB wird leider weiterhin die "Datenbankname.odb", also das Programm, aktualisiert, aber nicht die externen Daten. Dsgl. beim "Speichern" im Datenbankfenster. Erst beim vollständigen Schließen der Datenbank ändert sich das Datum der .data-Datei.
Da müsste dann doch eine laufende Änderung erfolgen, oder?
Ich habe hier keine HSQLDB extern laufen um das nach zu vollziehen.

Re: automatisches Backup und Zwischenspeichern (flush) bei externer hsqldb

Verfasst: Sa 9. Mär 2024, 16:46
von Aubergino
Danke schon mal an Freischreiber, aus Deinem Text habe ich jedenfalls schon mal entnommen, dass meine SUB zur Datensicherung so nicht hinreicht, weil sie nur die Datenbankname.data sichert. Da muss also auch noch die .script und die .log - Datei ge-filecopied werden...

Ansonsten beobachte ich den Disput gespannt...
Ich habe die Beobachtung, ob jederzeit in die .data geschrieben wurde oder erst zum Programmschluss anhand des "Änderungsdatums" in den Dateieigenschaften im Windows-Explorer gemacht.
Kann es denn sein, dass zwar stets aktuell eingeschrieben wird, die Datei aber bis zum Programmschluss geöffnet ist, das "Änderungsdatum" aber erst aktualisiert wird, wenn die Datei geschlossen wird?
Wenn Freischreiber recht hat, bedeutet das ja jedenfalls, dass eine SUB zum zwischendurch Speichern bei externer HSQLDB überflüssig ist.

Jetzt muss ich erst mal herausfinden, warum die Variante mit der externen DB bei mir zu Hause funktioniert, im Museum aber zum nur mit dem Taskmanager aufzulösenden Hängenbleiben von Libre Office führt... Aber nicht mehr heute...

Re: automatisches Backup und Zwischenspeichern (flush) bei externer hsqldb

Verfasst: Sa 9. Mär 2024, 18:06
von Freischreiber
RobertG hat geschrieben:
Sa 9. Mär 2024, 16:02
Hallo Freischreiber,

wie erklärst Du Dir dann aber die Beobachtung von Aubergino:
Bei der externen HSQLDB wird leider weiterhin die "Datenbankname.odb", also das Programm, aktualisiert, aber nicht die externen Daten. Dsgl. beim "Speichern" im Datenbankfenster. Erst beim vollständigen Schließen der Datenbank ändert sich das Datum der .data-Datei.
Da müsste dann doch eine laufende Änderung erfolgen, oder?
Ich habe hier keine HSQLDB extern laufen um das nach zu vollziehen.

Hallo Robert, hallo Aubergino,

offenbar ändert sich die odb-Datei durch dieses "Flush". Was das macht, weiß ich nicht, ich kenne das nicht. Vielleicht komprimiert dieses Flush ja (hier überflüssigerweise) die odb-Datei?

Meine odb-Datei ändert sich nur, wenn Abfragen, Views oder Formulare geändert werden. Ich glaube nicht einmal, wenn Tabellen per SQL verändert werden. Vorhin habe ich, um hier keinen Unsinn zu schreiben, LO und die Datenbank nach einer Datensatzänderung per Taskmanager abgeschossen. Danach wurde sie wegen der lck-Datei von Libreoffice "wiederhergestellt" und nicht einmal da hat sich die odb-Datei verändert. Nur die hsql-Dateien wurden konsolidiert (und die Datensatzänderung war noch da).

Jetzt habe ich noch einmal genauer hingeschaut. Meine externe HSQLDB hat (auch) cached tables.

Folgendes passiert:

Beim Starten einer vorher mit "shutdown script" geschlossenen Datenbank entsteht sofort eine 2 MB große data-Datei und eine 0 Byte große log-Datei. (Meine Datenbank ist relativ klein.)

Durch Datensatzänderungen ändert sich während der Laufzeit nur die log-Datei (und die properties-Datei springt auf modified=yes).

Durch Schließen der Datenbank verschwindet die log-Datei und die data- und die script-Datei werden aktualisiert. Vermutlich werden die Änderungen sowohl in die script-Datei geschrieben (den eigentlichen Speicherort der Daten) als auch der Cache in der data-Datei noch einmal aktualisiert.

In alle diese Dateien kannst du übrigens per Texteditor reinschauen, auch während die Datenbank geöffnet ist. Die log-Datei ist übersichtlich. Sie enthält genau das, was seit dem letzten Shutdown geändert wurde.

Auf der ganz sicheren Seite bist du folglich, wenn du zum gleichen Zeitpunkt, also egal ob die Datenbank gerade läuft oder nicht, alle (maximal 6) Dateien sicherst, deren Dateiname mit "datenbankname" anfängt, also datenbankname.log usw.

Zusätzlich kannst du die odb-Datei sichern.

Gruß
Freischreiber

PS: Bei mir entsteht übrigens beim Start keine lck-Datei der odb-Datei, so wie das bei Writer-Dateien der Fall ist. Nur eine datenbankname.lck, sobald ein Formular geöffnet wird.