PostgreSQL biedt een mooie BLOB-interface die veel wordt gebruikt. Echter, onlangs kwamen we problemen tegen van verschillende klanten, en het is zinvol om een beetje na te denken en erachter te komen hoe PostgreSQL BLOBs behandelt – en vooral BLOB cleanup.

met behulp van de PostgreSQL BLOB interface

In PostgreSQL kunt u verschillende manieren gebruiken om binaire gegevens op te slaan. De eenvoudigste vorm is zeker om gebruik te maken van het “bytea” (= byte array) gegevenstype. In dit geval wordt een binair veld in principe gezien als onderdeel van een Rij.
zo werkt het:

zoals u kunt zien, is dit een normale kolom en kan het net als een normale kolom worden gebruikt. Het enige dat het vermelden waard is, is de codering die men op het sql niveau moet gebruiken. PostgreSQL gebruikt een variabele om dit gedrag te configureren:

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

de bytea_output variabele accepteert twee waarden:” hex ” vertelt PostgreSQL om de gegevens in hex formaat te sturen. “escape” betekent dat data moet worden ingevoerd als een octale string. Er is niet veel de applicatie hoeft te maken over hier, afgezien van de maximale grootte van 1 GB per veld.
PostgreSQL heeft echter een tweede interface om binaire gegevens te verwerken: de blob-interface. Laat me een voorbeeld van deze krachtige tool in actie:

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

In dit geval is de inhoud van /etc/hosts geïmporteerd in de database. Merk op dat PostgreSQL een kopie van de gegevens heeft – het is geen link naar het bestandssysteem. Wat hier opmerkelijk is, is dat de database de OID (object ID) van het nieuwe item zal retourneren. Om deze OID ‘ s bij te houden, doen sommige ontwikkelaars het volgende:

INSERT 0 1

dit is absoluut prima, tenzij u iets doet zoals hieronder:

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

het probleem is dat het object-id is vergeten. Het object is er echter nog steeds. pg_largeobject is de systeemtabel die verantwoordelijk is voor het opslaan van de binaire gegevens in PostgreSQL. Alle lo_functions zullen gewoon met deze systeemtabel praten om deze dingen af te handelen:

Waarom is dat een probleem? De reden is eenvoudig: uw database zal groeien en het aantal “dode objecten” zal accumuleren. Daarom is de juiste manier om een BLOB entry te doden als volgt:

als u vergeet het object te ontkoppelen, zult u op de lange termijn lijden – en we hebben dat vaak zien gebeuren. Het is een groot probleem als u gebruik maakt van de blob-interface.

vacuumlo: opruimen van dode grote objecten

Hoe kan men het probleem oplossen als u duizenden, of misschien miljoenen dode BLOBs hebt verzameld? Het antwoord is een command line tool genaamd “vacuumlo”.
laten we eerst een dode regel maken:

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

dan kunnen we vacuumlo uitvoeren vanaf elke client:

zoals je kunt zien, zijn er twee dode objecten gedood door het gereedschap. vacuumlo is de makkelijkste manier om verweesde objecten schoon te maken.

extra functionaliteit

er is echter meer dan alleen lo_import en lo_unlink. PostgreSQL biedt een verscheidenheid aan functies om grote objecten op een mooie manier te behandelen:

er zijn nog twee functies die om historische redenen niet de naamgevingsconventie volgen: loread en lowrite:

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

het zijn functies waarvan de namen niet gemakkelijk meer veranderd kunnen worden. Het is echter vermeldenswaard dat ze bestaan.

tenslotte …

de PostgreSQL BLOB interface is echt nuttig en kan voor veel dingen worden gebruikt. Het mooie is dat het volledig transactioneel is en daarom kunnen binaire inhoud en metadata niet meer synchroon lopen.

Als u meer wilt weten over triggers om beperkingen af te dwingen in PostgreSQL, raden wij u aan onze blogpost geschreven door Laurenz Albe te bekijken. Het zal enig licht werpen op dit belangrijke onderwerp.

Geef een antwoord

Het e-mailadres wordt niet gepubliceerd.