49.2. TOAST

Cette section fournit un aper�u de TOAST (The Oversized-Attribute Storage Technique, la technique de stockage des attributs trop grands).

Puisque PostgreSQL utilise une taille de page fixe (habituellement 8 Ko) et n'autorise pas qu'une ligne s'�tende sur plusieurs pages, il n'est pas possible de stocker de grandes valeurs directement dans les champs. Avant PostgreSQL 7.1, il existait une limite en dur juste en-dessous d'une page pour la taille totale des donn�es d'une ligne de table. A partir de la version 7.1, cette limite est d�pass�e en permettant de compresser des valeurs de champ volumineuses et/ou de les diviser en plusieurs lignes physiques. Ceci survient de fa�on transparente pour l'utilisateur, avec seulement un petit impact sur le code du serveur. Cette technique est connu sous l'acronyme affectueux de TOAST (ou <<�the best thing since sliced bread�>>).

Seuls certains types de donn�es supportent TOAST — il n'est pas n�cessaire d'imposer cette surcharge sur les types de donn�es qui ne produisent pas de gros volumes. Pour supporter TOAST, un type de donn�es doit avoir une repr�sentation (varlena) � longueur variable, dans laquelle les 32 premiers bits contiennent la longueur totale de la valeur en octets (ceci incluant la longueur elle-m�me). TOAST n'a aucune contrainte suppl�mentaire sur la repr�sentation. Toutes les fonctions niveau C qui g�rent un type donn�es supportant TOAST doivent faire attention � g�rer les valeurs en entr�e TOAST�es. (Ceci se fait normalement en appelant PG_DETOAST_DATUM avant de faire quoi que ce soit avec une valeur en entr�e; mais dans certains cas, des approches plus efficaces sont possibles.)

TOAST empi�te les deux bits de poids fort sur le mot contenant la longueur varlena, limitant par cons�quent la taille logique de toute valeur d'un type de donn�es TOAST-able � 1 Go (230 - 1 octets). Quand les deux bits sont � z�ro, cette valeur est une valeur ordinaire, non TOAST�e, du type de donn�es. Un des bits initialis� indique que la valeur a �t� compress�e et doit �tre d�compress�e avant d'�tre utilis�e. L'autre bit indique que la valeur a �t� stock� en dehors de la ligne. Dans ce cas, le reste de la valeur est en r�alit� simplement un pointeur et la v�ritable donn�e se trouve ailleurs. Quand les deux bits sont initialis�s, les donn�es sont stock�es ailleurs tout en �tant compress�es. Dans tous les cas, la longueur dans les bits de poids faible du mot varlena indique la taille r�elle de la donn�e, pas la taille de la valeur logique qui serait extraite par d�compression ou r�cup�ration de la donn�e en dehors de la ligne.

Si une des colonnes d'une table est TOAST-able, la table disposera d'une table TOAST associ�, dont l'OID est stock�e dans l'entr�e pg_class.reltoastrelid de la table. Les valeurs TOAST�es hors-ligne sont conserv�es dans la table TOAST comme d�crit avec plus de d�tails ci-dessous.

La technique de compression utilis�e est un simple et rapide membre de la famille des techniques de compression LZ. Voir src/backend/utils/adt/pg_lzcompress.c pour les d�tails.

Les valeurs hors-ligne sont divis�es (apr�s compression si n�cessaire) en morceaux d'au plus TOAST_MAX_CHUNK_SIZE octets (cette valeur est un peu plus petite que BLCKSZ/4, soit � peu pr�s 2000 octets par d�faut). Chaque morceau est stock� comme une ligne s�par�e dans la table TOAST de la table propri�taire. Chaque table TOAST contient les colonnes chunk_id (un OID identifiant la valeur TOAST�e particuli�re), chunk_seq (un num�ro de s�quence pour le morceau de la valeur) et chunk_data (la donn�e r�elle du morceau). Un index unique sur chunk_id et chunk_seq offre une r�cup�ration rapide des valeurs. Un pointeur datum repr�sentant une valeur TOAST�e hors-ligne a par cons�quent besoin de stocker l'OID de la table TOAST dans laquelle chercher et l'OID de la valeur sp�cifique (son chunk_id). Par commodit�, les pointeurs datums stockent aussi la taille logique du datum (taille de la donn�e originale non compress�e) et la taille stock�e r�elle (diff�rente si la compression a �t� appliqu�e). A partir du mot d'en-t�te varlena, la taille totale d'un pointeur datum TOAST est par cons�quent de 20 octets quelque soit la taille r�elle de la valeur repr�sent�e.

Le code TOAST est d�clench� seulement quand une valeur de ligne � stocker dans une table est plus grande que BLCKSZ/4 octets (habituellement 2 Ko). Le code TOAST compressera et/ou d�placera les valeurs de champ hors la ligne jusqu'� ce que la valeur de la ligne soit plus petite que BLCKSZ/4 octets ou que plus aucun gain ne puisse �tre r�alis�. Lors d'une op�ration UPDATE, les valeurs des champs non modifi�es sont habituellement pr�serv�es telles quelles ; donc un UPDATE sur une ligne avec des valeurs hors ligne n'induit pas de co�ts � cause de TOAST si aucune des valeurs hors-ligne n'est modifi�e.

Le code TOAST conna�t quatre strat�gies diff�rentes pour stocker les colonnes TOAST-ables :

Chaque type de donn�es TOAST-able sp�cifie une strat�gie par d�faut pour les colonnes de ce type de donn�e, mais la strat�gie pour une colonne d'une table donn�e peut �tre modifi�e avec ALTER TABLE SET STORAGE.

Cette combinaison a de nombreux avantages compar�s � une approche plus directe comme autoriser le stockage des valeurs de lignes sur plusieurs pages. En supposant que les requ�tes sont habituellement qualifi�es par comparaison avec des valeurs de cl� relativement petites, la grosse partie du travail de l'ex�cuteur sera r�alis�e en utilisant l'entr�e principale de la ligne. Les grandes valeurs des attributs TOAST�s seront seulement r�cup�r�es (si elles sont s�lectionn�es) au moment o� l'ensemble de r�sultats est envoy� au client. Ainsi, la table principale est bien plus petite et un plus grand nombre de ses lignes tiennent dans le cache du tampon partag�, ce qui ne serait pas le cas sans aucun stockage hors-ligne. Le tri l'utilise aussi, et les tris seront plus souvent r�alis�s enti�rement en m�moire. Un petit test a montr� qu'une table contenant des pages HTML typiques ainsi que leurs URL �taient stock�es en � peu pr�s la moiti� de la taille des donn�es brutes en incluant la table TOAST et que la table principale contenait moins de 10 % de la totalit� des donn�es (les URL et quelques petites pages HTML). Il n'y avait pas de diff�rence � l'ex�cution en comparaison avec une table non TOAST�e, dans laquelle toutes les pages HTLM avaient �t� coup�es � 7 Ko pour tenir.