PostgreSQL offre una bella interfaccia BLOB che è ampiamente utilizzato. Tuttavia, recentemente ci siamo imbattuti in problemi affrontati da vari clienti, e ha senso riflettere un po ‘ e capire come PostgreSQL gestisce BLOB – e in particolare BLOB cleanup.

Utilizzando l’interfaccia BLOB PostgreSQL

In PostgreSQL, è possibile utilizzare vari mezzi per memorizzare dati binari. La forma più semplice è sicuramente quella di utilizzare il tipo di dati “bytea” (= byte array). In questo caso un campo binario è fondamentalmente visto come parte di una riga.
Ecco come funziona:

Come puoi vedere, questa è una colonna normale e può essere utilizzata proprio come una colonna normale. L’unica cosa che vale la pena menzionare è la codifica che si deve usare a livello SQL. PostgreSQL utilizza una variabile per configurare questo comportamento:

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

La variabile bytea_output accetta due valori: “hex” dice a PostgreSQL di inviare i dati in formato hex. “escape” significa che i dati devono essere inseriti come una stringa ottale. Non c’è molto l’applicazione deve preoccuparsi qui, a parte la dimensione massima di 1 GB per campo.
Tuttavia, PostgreSQL ha una seconda interfaccia per gestire i dati binari: L’interfaccia BLOB. Permettetemi di mostrare un esempio di questo potente strumento in azione:

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

In questo caso, il contenuto di /etc/hosts è stato importato nel database. Si noti che PostgreSQL ha una copia dei dati – non è un collegamento al filesystem. Ciò che è degno di nota qui è che il database restituirà l’OID (ID oggetto) della nuova voce. Per tenere traccia di questi OID, alcuni sviluppatori fanno quanto segue:

INSERT 0 1

Questo va assolutamente bene, a meno che tu non faccia qualcosa di simile qui sotto:

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

Il problema è che l’id oggetto è stato dimenticato. Tuttavia, l’oggetto è ancora lì. pg_largeobject è la tabella di sistema incaricata di memorizzare i dati binari all’interno di PostgreSQL. Tutte le lo_functions parleranno semplicemente con questa tabella di sistema per gestire queste cose:

Perché è un problema? Il motivo è semplice: il tuo database crescerà e il numero di “oggetti morti” si accumulerà. Pertanto il modo corretto per uccidere una voce BLOB è il seguente:

Se dimentichi di scollegare l’oggetto, ne soffrirai a lungo termine – e lo abbiamo spesso visto accadere. Si tratta di un problema importante se si utilizza l’interfaccia BLOB.

vacuumlo: ripulire oggetti di grandi dimensioni morti

Tuttavia, come si può risolvere il problema una volta accumulati migliaia, o forse milioni, di BLOB morti? La risposta è uno strumento da riga di comando chiamato “vacuumlo”.
Creiamo prima una voce morta:

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

Quindi possiamo eseguire vacuumlo da qualsiasi client:

Come puoi vedere, due oggetti morti sono stati uccisi dallo strumento. vacuumlo è il modo più semplice per pulire gli oggetti orfani.

Funzionalità aggiuntive

Tuttavia, non ci sono solo lo_import e lo_unlink. PostgreSQL offre una varietà di funzioni per gestire oggetti di grandi dimensioni in un modo carino:

Ci sono altre due funzioni che non seguono la convenzione di denominazione per ragioni storiche: loread e lowrite:

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

Sono funzioni i cui nomi non possono più essere facilmente modificati. Tuttavia, vale la pena notare che esistono.

Finalmente

L’interfaccia BLOB di PostgreSQL è davvero utile e può essere usata per molte cose. Il bello è che è completamente transazionale e quindi il contenuto binario e i metadati non possono più essere sincronizzati.

Se vuoi saperne di più sui trigger per applicare i vincoli in PostgreSQL, ti consigliamo di controllare il nostro post sul blog scritto da Laurenz Albe. Farà luce su questo importante argomento.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.