Documentation PostgreSQL 8.0.2 | ||||
---|---|---|---|---|
Précédent | Arrière rapide | Chapitre 49. Stockage physique de la base de données | Avance rapide | Suivant |
Cette section fournit un aperçu de TOAST (The Oversized-Attribute Storage Technique, la technique de stockage des attributs trop grands).
Comme PostgreSQL utilise une taille de page fixe (habituellement 8 Ko) et n'autorise pas qu'une ligne soit 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 qui valait juste en-dessous d'une page pour la taille totale d'une donnée sur une ligne d'une table. A partir de la version 7.1, cette limite est dépassée en permettant de compresser des valeurs plus importantes 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. La 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 la surcharge sur les types de données qui ne
produisent pas de grosses valeurs de données. Pour supporter
TOAST, un type de données doit avoir une représentation
(varlena) à longueur variable, dans laquelle les premiers 32 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 supportant 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 usurpe les deux bits de poids fort dans le mot contenant la longueur varlena, limitant du coup 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 indique que la valeur a été stocké ailleurs. Dans ce cas, le reste de la valeur est réellement un pointeur et la vraie 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 chaque cas, la longueur dans les bits de poids faible du mot varlena indique la taille du datum, pas la taille de la valeur logique qui serait extraite par la décompression ou la récupération de la donnée.
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 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 morceau 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 fournit une récupération rapide des valeurs. Un pointeur datum représentant une valeur TOASTée hors-ligne a du coup besoin de stocker l'OID de la table TOAST dans laquelle chercher et l'OID de la valeur spécifique (son chunk_id). Pour la facilité, les pointeurs datums stockent aussi la tille 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 du coup 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 d'une ligne à stocker est plus grande que BLCKSZ/4 octets (habituellement 2 Ko). Le code TOAST compressera et/ou déplacera les valeurs de champ jusqu'à ce que la valeur de la ligne soit plus petite que BLCKSZ/4 octets ou qu'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 ainsi ; 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 reconnaît quatre stratégies différentes pour stocker les colonnes TOAST-able :
PLAIN empêche soit la compression soit le stockage hors-ligne. Ceci est la seule stratégie possible strategy pour les colonnes des types de données non TOAST-ables.
EXTENDED permet à la fois la compression et le stockage hors-ligne. Ceci est la valeur par défaut de la plupart des types de données TOAST-ables. La compression sera tentée en premier, puis le stockage hors-ligne si la ligne est toujours trop grande.
EXTERNAL autorise le stockage hors-ligne mais pas la compression. L'utilisation d'EXTERNAL rendra les opérations sur des sous-chaînes de grosses colonnes de type text et bytea plus rapide (au dépens d'un espace de stockage accrus) car ces opérations sont optimisées pour récupérer seulement les parties requises de la valeur hors-ligne lorsqu'elle n'est pas compressée.
MAIN autorise la compression mais pas le stockage hors-ligne. (En fait, le stockage hors-ligne sera toujours réalisé pour de tels colonnes mais seulement comme dernier ressort s'il n'existe aucune autre solution pour diminuer suffisament la taille de la ligne.)
Chaque type de données TOAST-able spécifie une stratégie 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.
Ce schéma a un certain nombre d'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'entére 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. Du coup, la table principale est bien plus petite et un plus grand nombre de ses lignes tient dans le cache du tampon partagé. Le tri l'utilise aussi et les tris seront réalisés le plus souvent entièrement en mémoire. Un petit test a montré qu'une table contenant des pages HTML typiques ainsi que les URL étaient stockées en mémoire sur 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 a pas de différence à l'exécution en comparaison avec une table non TOASTée, dans laquelle toutes les pages HTLM ont été coupée à 7 Ko pour tenir.
Précédent | Sommaire | Suivant |
Stockage physique de la base de données | Niveau supérieur | Emplacement des pages de la base de données |