PostgreSQL bietet eine schöne BLOB-Schnittstelle, die weit verbreitet ist. In letzter Zeit sind wir jedoch auf Probleme verschiedener Kunden gestoßen, und es ist sinnvoll, ein wenig darüber nachzudenken, wie PostgreSQL mit BLOBs umgeht – und insbesondere mit der BLOB-Bereinigung.

Verwenden der PostgreSQL-BLOB-Schnittstelle

In PostgreSQL können Sie Binärdaten mit verschiedenen Mitteln speichern. Die einfachste Form ist definitiv die Verwendung des Datentyps „bytea“ (= Byte Array). In diesem Fall wird ein Binärfeld grundsätzlich als Teil einer Zeile gesehen.
So funktioniert es:

Wie Sie sehen können, ist dies eine normale Spalte und kann wie eine normale Spalte verwendet werden. Das einzige, was erwähnenswert ist, ist die Codierung, die man auf SQL-Ebene verwenden muss. PostgreSQL verwendet eine Variable, um dieses Verhalten zu konfigurieren:

test=# SHOW bytea_output;bytea_output--------------hex(1 row)

Die Variable bytea_output akzeptiert zwei Werte: „hex“ weist PostgreSQL an, die Daten im Hex-Format zu senden. „escape“ bedeutet, dass Daten als oktale Zeichenfolge eingegeben werden müssen. Abgesehen von der maximalen Größe von 1 GB pro Feld muss sich die Anwendung hier nicht um viel kümmern.
PostgreSQL verfügt jedoch über eine zweite Schnittstelle zur Verarbeitung von Binärdaten: Die BLOB-Schnittstelle. Lassen Sie mich ein Beispiel für dieses leistungsstarke Tool in Aktion zeigen:

test=# SELECT lo_import('/etc/hosts');lo_import-----------80343(1 row)

In diesem Fall wurde der Inhalt von /etc/hosts in die Datenbank importiert. Beachten Sie, dass PostgreSQL eine Kopie der Daten hat – es ist kein Link zum Dateisystem. Bemerkenswert ist hier, dass die Datenbank die OID (Objekt-ID) des neuen Eintrags zurückgibt. Um diese OIDs im Auge zu behalten, führen einige Entwickler Folgendes aus:

INSERT 0 1

Das ist absolut in Ordnung, es sei denn, Sie tun etwas wie unten:

test=# DELETE FROM t_file WHERE id = 1;DELETE 1

Das Problem ist, dass die Objekt-ID vergessen wurde. Das Objekt ist jedoch immer noch da. pg_largeobject ist die Systemtabelle, die für die Speicherung der Binärdaten in PostgreSQL verantwortlich ist. Alle lo_functions sprechen einfach mit dieser Systemtabelle, um diese Dinge zu behandeln:

Warum ist das ein Problem? Der Grund ist einfach: Ihre Datenbank wird wachsen und die Anzahl der „toten Objekte“ wird sich ansammeln. Daher ist der richtige Weg, einen BLOB-Eintrag zu beenden, wie folgt:

Wenn Sie vergessen, das Objekt zu trennen, werden Sie auf lange Sicht leiden – und das haben wir oft gesehen. Es ist ein großes Problem, wenn Sie die BLOB-Schnittstelle verwenden.

vacuumlo: Aufräumen toter großer Objekte

Wie kann man das Problem jedoch beheben, wenn man Tausende oder vielleicht Millionen toter BLOBs angesammelt hat? Die Antwort ist ein Befehlszeilentool namens „vacuumlo“.
Lassen Sie uns zuerst einen toten Eintrag erstellen:

test=# SELECT lo_import('/etc/hosts');lo_import-----------80351(1 row)

Dann können wir vacuumlo von jedem Client aus ausführen:

Wie Sie sehen, wurden zwei tote Objekte vom Tool getötet. vacuumlo ist der einfachste Weg, um verwaiste Objekte zu reinigen.

Zusätzliche Funktionalität

Es gibt jedoch mehr als nur lo_import und lo_unlink. PostgreSQL bietet eine Vielzahl von Funktionen, um große Objekte auf nette Weise zu behandeln:

Es gibt zwei weitere Funktionen, die aus historischen Gründen nicht der Namenskonvention folgen: loread und lowrite:

pg_catalog | loread | bytea | integer, integer | funcpg_catalog | lowrite | integer | integer, bytea | func

Es sind Funktionen, deren Namen nicht mehr einfach geändert werden können. Es ist jedoch erwähnenswert, dass sie existieren.

Schließlich …

Die PostgreSQL-BLOB-Schnittstelle ist sehr nützlich und kann für viele Dinge verwendet werden. Das Schöne ist, dass es vollständig transaktional ist und daher binäre Inhalte und Metadaten nicht mehr synchron sein können.

Wenn Sie mehr über Trigger zum Erzwingen von Einschränkungen in PostgreSQL erfahren möchten, empfehlen wir Ihnen, unseren Blogbeitrag von Laurenz Albe zu lesen. Es wird etwas Licht in dieses wichtige Thema bringen.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.