Beispiel update Blob-Feld

Themen rund um den praktischen Einsatz von Firebird. Fragen zu SQL, Performance, Datenbankstrukturen, etc.

Moderator: thorben.braun

Hamburgo
Beiträge: 46
Registriert: Di 28. Mai 2019, 17:28

Hallo Martin,

so, die Haupt-Herausforderung ist gelöst. Grandios !!!

Herzlichen Dank für Deine geduldige Unterstützung !!!

Jetzt sind meines Erachtens nach nur noch 2 kleine Lücken zu schließen,
aber nur auf der Ebene von "nice to have", also sekundäre Priorität.

1. Derzeit wächst bei mir die DB kontinuierlich weiter an, auch wenn ich
dasselbe Bild mehrfach hintereinander einlese.
Gibt es evtl. einen Trick, wie man ein existierendes Blob updaten kann ?

2. Kann man ein Blob löschen bzw. freigeben zum über-schreiben ?
Benutzeravatar
martin.koeditz
Beiträge: 283
Registriert: Sa 31. Mär 2018, 14:35

1. Derzeit wächst bei mir die DB kontinuierlich weiter an, auch wenn ich
dasselbe Bild mehrfach hintereinander einlese.
Gibt es evtl. einen Trick, wie man ein existierendes Blob updaten kann ?
Dies ist designabhängig in Firebird. BLOBs werden in eigenen Seiten gespeichert. Jedes Bild reserviert einen weiteren Bereich. Damit wächst die DB. Firebird-DBs "schrumpfen" nicht mehr. Wird ein BLOB gelöscht oder auf NULL gesetzt, ist der jeweilige Seitenbereich wieder frei und wird für neue Daten genutzt. Aber wie gesagt, die DB wird nicht mehr kleiner. Da hilft nur Backup & Restore.

Wie kann man ein exestierendes BLOB aktualisieren? Nur über die normale UPDATE-Klausel. Es gibt m.E. keine Möglichkeit nur über die interne BLOB-ID zu gehen.

Weitere Interna zur Speicherung von BLOBs findest du hier:
https://firebirdsql.org/file/documentat ... es-more-de
2. Kann man ein Blob löschen bzw. freigeben zum über-schreiben ?
Gesamte Zeile löschen oder Update durchführen und Feld auf NULL setzen. In beiden Fällen wird der Speicher für den Garbage Collector markiert und beim nächsten "Sweep" wieder freigegeben.

Gruß
Martin
Martin Köditz
it & synergy GmbH
bfuerchau
Beiträge: 276
Registriert: Mo 7. Mai 2018, 18:09

Durch die Versionierung der Daten bleiben die alten Daten erhalten, bis:
- der Sweep (Garbagecollector) nach 20.000 Transaktionen zuschlägt
- die Tabelle mit einer neuen Transaktion mal wieder gelesen wird.
Zu letzterem reicht ein Abfragen des ID-Feldes, da ja die Satzversion nicht einzelne Felder (auch Blobs) betrifft.

In der Tabelle MON$DATABASE gibt es entsprechenden Transaktionsnummern. Das Problem sind immer die sog. "ältesteste interessante Transaktion".
Solange also noch Transaktionen offen sind, die älter sind als die Transaktion, die gerade die neue Satzversion erstellt hat, bleiben alte Satzversion erhalten.
Der Besitzer der alten Transaktion (Connection) könnte die Daten ja noch haben wollen.

Sobald die Daten freigegeben werden können, werden sie auch wiederverwendet und die DB wächst nicht mehr so schnell.

Beachte also das Transaktionsverhalten, verwende Transaktion überhaupt, und commmitte diese entsprechend.
Auch wenn es keinen Sinn zu machen scheint: gerade beim Satzversioning wie in der FB muss man auch für Select-Operationen Transaktionen starten und committen, um immer die aktuellsten Werte zu erhalten.
Antworten