Si vous travaillez avec de grandes bases de données dans Postgres , cette histoire vous semblera familière. À mesure que votre base de données Postgres continue de croître, vos performances commencent à décliner et vous commencez à vous soucier de l'espace de stockage ou, pour être précis, du prix que vous allez payer pour cela. Vous aimez PostgreSQL, mais il y a quelque chose que vous souhaiteriez avoir : un mécanisme de compression de données très efficace.
PostgreSQL dispose en quelque sorte d'un mécanisme de compression :
Même si cela peut réduire la taille des ensembles de données, TOAST (The surdimensionné Attribute Storage Technique) n'est pas votre mécanisme de compression de données traditionnel. Pour comprendre ce qu'est TOAST, il faut commencer par parler de
Les unités de stockage de Postgres sont appelées pages et celles-ci ont une taille fixe (8 Ko par défaut). Avoir une taille de page fixe donne à Postgres de nombreux avantages, à savoir sa simplicité, son efficacité et sa cohérence en matière de gestion des données, mais cela présente un inconvénient : certaines valeurs de données peuvent ne pas tenir dans cette page.
C'est là qu'intervient TOAST. TOAST fait référence au mécanisme automatique que PostgreSQL utilise pour stocker et gérer efficacement les valeurs dans Postgres qui ne tiennent pas dans une page. Pour gérer de telles valeurs, Postgres TOAST les compressera, par défaut, à l'aide d'un algorithme interne. Si, après compression, les valeurs sont encore trop grandes, Postgres les déplacera vers une table séparée (appelée table TOAST), laissant les pointeurs dans la table d'origine.
Comme nous le verrons plus loin dans cet article, vous pouvez réellement modifier cette stratégie en tant qu'utilisateur, par exemple en disant à Postgres d'éviter de compresser les données dans une colonne particulière.
Les types de données susceptibles d'être soumis à TOAST sont principalement ceux de longueur variable qui peuvent potentiellement dépasser les limites de taille d'une page PostgreSQL standard. D'un autre côté, les types de données de longueur fixe, comme integer
, float
ou timestamp
, ne sont pas soumis à TOAST car ils s'intègrent confortablement dans une page.
Voici quelques exemples de types de données pouvant être soumis à TOAST :
json
et jsonb
Grandes chaînes text
varchar
et varchar(n)
(Si la longueur spécifiée dans varchar(n)
est suffisamment petite, alors les valeurs de cette colonne peuvent toujours rester en dessous du seuil TOAST.)
bytea
stockant des données binaires
Données géométriques telles que path
et polygon
et types PostGIS comme geometry
ou geography
Comprendre TOAST ne concerne pas seulement le concept de taille de page mais également un autre concept de stockage Postgres : les tuples. Les tuples sont des lignes dans une table PostgreSQL. En règle générale, le mécanisme TOAST entre en jeu si tous les champs d'un tuple ont une taille totale supérieure à 2 Ko environ.
Si vous avez prêté attention, vous vous demandez peut-être : « Attendez, mais la taille de la page est d'environ 8 Ko, pourquoi cette surcharge ? » En effet, PostgreSQL aime s'assurer qu'il peut stocker plusieurs tuples sur une seule page : si les tuples sont trop grands, moins de tuples tiennent sur chaque page, ce qui entraîne une augmentation des opérations d'E/S et une réduction des performances.
Postgres doit également conserver de l'espace libre pour accueillir des données opérationnelles supplémentaires : chaque page stocke non seulement les données du tuple, mais également des informations supplémentaires pour la gestion des données, telles que les identifiants d'éléments, les en-têtes et les informations de transaction.
Ainsi, lorsque la taille combinée de tous les champs d'un tuple dépasse environ 2 Ko (ou le paramètre de seuil TOAST, comme nous le verrons plus tard), PostgreSQL prend des mesures pour garantir que les données sont stockées efficacement. TOAST gère cela de deux manières principales :
Compression. PostgreSQL peut compresser les grandes valeurs de champ dans le tuple pour réduire leur taille à l'aide d'un algorithme de compression que nous aborderons plus loin dans cet article. Par défaut, si la compression est suffisante pour ramener la taille totale du tuple en dessous du seuil, les données resteront dans la table principale, bien que dans un format compressé.
Stockage hors ligne. Si la compression seule n'est pas suffisamment efficace pour réduire la taille des grandes valeurs de champ, Postgres les déplace vers une table TOAST distincte. Ce processus est appelé stockage « hors ligne » car le tuple d'origine de la table principale ne contient plus les grandes valeurs de champ. Au lieu de cela, il contient un « pointeur » ou une référence à l'emplacement des données volumineuses dans la table TOAST.
Nous simplifions légèrement les choses pour cet article—
pglz
Nous avons mentionné que TOAST peut compresser des valeurs volumineuses dans PostgreSQL. Mais quel algorithme de compression PostgreSQL utilise-t-il et quelle est son efficacité ?
Le pglz
(PostgreSQL Lempel-Ziv) est l'algorithme de compression interne par défaut utilisé par PostgreSQL spécifiquement adapté à TOAST.
Voici comment cela fonctionne en termes très simples :
pglz
essaie d'éviter les données répétées. Lorsqu'il voit des données répétées, au lieu d'écrire à nouveau la même chose, il renvoie simplement à l'endroit où il l'a écrit auparavant. Cette « évitation des répétitions » permet de gagner de la place.
Lorsque pglz
lit les données, il se souvient d'une partie des données récentes qu'il a vues. Cette mémoire récente est appelée « fenêtre glissante ».
Au fur et à mesure que de nouvelles données arrivent, pglz
vérifie s'il a vu ces données récemment (dans sa fenêtre glissante). Si oui, il écrit une courte référence au lieu de répéter les données.
Si les données sont nouvelles ou ne sont pas répétées suffisamment de fois pour rendre une référence plus courte que les données réelles, pglz
les écrit simplement telles quelles.
Lorsqu'il est temps de lire les données compressées, pglz
utilise ses références pour récupérer les données originales. Ce processus est assez direct, car il recherche les données référencées et les place à leur place.
pglz
n'a pas besoin de stockage séparé pour sa mémoire (la fenêtre coulissante) ; il le construit en déplacement lors de la compression et fait de même lors de la décompression.
Cette implémentation est conçue pour offrir un équilibre entre l'efficacité de la compression et la vitesse au sein du mécanisme TOAST. En termes de taux de compression, l'efficacité de pglz
dépendra largement de la nature des données.
Par exemple, les données très répétitives seront bien mieux compressées que les données à haute entropie (comme les données aléatoires). Vous pouvez constater des taux de compression compris entre 25 et 50 %, mais il s'agit d'une estimation très générale : les résultats varient considérablement en fonction de la nature exacte des données.
Par défaut, PostgreSQL passera par le mécanisme TOAST selon la procédure expliquée précédemment (compression d'abord et stockage hors ligne ensuite, si la compression n'est pas suffisante). Néanmoins, il peut exister des scénarios dans lesquels vous souhaiterez peut-être affiner ce comportement colonne par colonne. PostgreSQL vous permet de le faire en utilisant les stratégies TOAST PLAIN
, EXTERNAL
, EXTENDED
et MAIN
.
EXTENDED
: C'est la stratégie par défaut. Cela implique que les données seront stockées hors ligne dans une table TOAST distincte si elles sont trop volumineuses pour une page de table normale. Avant de déplacer les données vers la table TOAST, elles seront compressées pour économiser de l'espace.
EXTERNAL
: Cette stratégie indique à PostgreSQL de stocker les données de cette colonne hors ligne si les données sont trop volumineuses pour tenir dans une page de table normale, et nous demandons à PostgreSQL de ne pas compresser les données : la valeur sera simplement déplacée vers la page de table standard. Table TOAST telle quelle.
MAIN
: Cette stratégie est un juste milieu. Il essaie de maintenir les données alignées dans la table principale grâce à la compression ; si les données sont définitivement trop volumineuses, elles seront déplacées vers la table TOAST pour éviter une erreur, mais PostgreSQL ne déplacera pas les données compressées. Au lieu de cela, il stockera la valeur dans la table TOAST sous sa forme originale.
PLAIN
: L'utilisation PLAIN
dans une colonne indique à PostgreSQL de toujours stocker les données de la colonne en ligne dans la table principale, garantissant qu'elles ne sont pas déplacées vers une table TOAST hors ligne. Tenez compte du fait que si les données dépassent la taille de la page, l' INSERT
échouera car les données ne rentreront pas.
Si vous souhaitez inspecter les stratégies actuelles d'une table particulière, vous pouvez exécuter ce qui suit :
\d+ your_table_name
Vous obtiendrez un résultat comme celui-ci :
=> \d+ example_table Table "public.example_table" Column | Data Type | Modifiers | Storage | Stats target | Description ---------+------------------+-----------+----------+--------------+------------- bar | varchar(100000) | | extended | |
Si vous souhaitez modifier le paramètre de stockage, vous pouvez le faire à l'aide de la commande suivante :
-- Sets EXTENDED as the TOAST strategy for bar_column ALTER TABLE example_blob ALTER COLUMN bar_column SET STORAGE EXTENDED;
Outre les stratégies ci-dessus, ces deux paramètres sont également importants pour contrôler le comportement de TOAST :
TOAST_TUPLE_THRESHOLD
Il s'agit du paramètre qui définit le seuil de taille lorsque les opérations TOASTing (compression et stockage hors ligne) sont prises en compte pour les tuples surdimensionnés.
Comme nous l'avons mentionné précédemment, par défaut, TOAST_TUPLE_THRESHOLD
est défini sur environ 2 Ko.
TOAST_COMPRESSION_THRESHOLD
Il s'agit du paramètre qui spécifie la taille minimale d'une valeur avant que Postgres n'envisage de la compresser pendant le processus TOASTing.
Si une valeur dépasse ce seuil, PostgreSQL tentera de la compresser. Cependant, ce n'est pas parce qu'une valeur est supérieure au seuil de compression qu'elle sera automatiquement compressée : les stratégies TOAST guideront PostgreSQL sur la façon de gérer les données en fonction de leur compression et de leur taille résultante par rapport au tuple et limites de pages, comme nous le verrons dans la section suivante.
TOAST_TUPLE_THRESHOLD
est le point de déclenchement. Lorsque la taille des champs de données combinés d'un tuple dépasse ce seuil, PostgreSQL évalue comment le gérer en fonction de la stratégie TOAST définie pour ses colonnes, en tenant compte de la compression et du stockage hors ligne. Les actions exactes entreprises dépendront également du fait que les données de la colonne dépassent le TOAST_COMPRESSION_THRESHOLD
:
EXTENDED
(stratégie par défaut) : si la taille d'un tuple dépasse TOAST_TUPLE_THRESHOLD
, PostgreSQL tentera d'abord de compresser les colonnes surdimensionnées si elles dépassent également TOAST_COMPRESSION_THRESHOLD
. Si la compression ramène la taille du tuple en dessous du seuil, il restera dans la table principale. Si ce n'est pas le cas, les données seront déplacées vers une table TOAST hors ligne et la table principale contiendra des pointeurs vers ces données externes.
MAIN
: Si la taille du tuple dépasse TOAST_TUPLE_THRESHOLD
, PostgreSQL tentera de compresser les colonnes surdimensionnées (à condition qu'elles dépassent TOAST_COMPRESSION_THRESHOLD
). Si la compression permet au tuple de s'insérer dans le tuple de la table principale, il y reste. Dans le cas contraire, les données sont déplacées vers la table TOAST sous leur forme non compressée.
EXTERNAL
: PostgreSQL ignore la compression, quel que soit le TOAST_COMPRESSION_THRESHOLD
. Si la taille du tuple dépasse TOAST_TUPLE_THRESHOLD
, les colonnes surdimensionnées seront stockées hors ligne dans la table TOAST.
PLAIN
: Les données sont toujours stockées dans la table principale. Si la taille d'un tuple dépasse la taille de la page (en raison de très grandes colonnes), une erreur est générée.
Stratégie | Compresser si tuple > TOAST_COMPRESSION_THRESHOLD | Stocker hors ligne si tuple > TOAST_TUPLE_THRESHOLD | Description |
---|---|---|---|
ÉTENDU | Oui | Oui | Stratégie par défaut. Compresse d'abord, puis vérifie si un stockage hors ligne est nécessaire. |
PRINCIPAL | Oui | Uniquement sous forme non compressée | Compresse d'abord, et si elle est toujours surdimensionnée, passe à la table TOAST sans compression. |
EXTERNE | Non | Oui | Se déplace toujours vers TOAST si surdimensionné, sans compression. |
PLAINE | Non | Non | Les données restent toujours dans la table principale. Si un tuple dépasse la taille de la page, une erreur se produit. |
À présent, vous comprendrez probablement pourquoi TOAST n'est pas le mécanisme de compression de données que vous souhaiteriez avoir dans PostgreSQL. Les applications modernes impliquent l’ingestion quotidienne de gros volumes de données, ce qui signifie que les bases de données (sur)croissent rapidement.
Un tel problème n'était pas aussi important lors de la création de notre bien-aimé Postgres il y a plusieurs décennies, mais les développeurs d'aujourd'hui ont besoin de solutions de compression pour réduire l'empreinte de stockage de leurs ensembles de données.
Bien que TOAST intègre la compression comme l'une de ses techniques, il est crucial de comprendre que son rôle principal n'est pas de servir de mécanisme de compression de base de données au sens traditionnel du terme. TOAST est principalement une solution à un problème : gérer de grandes valeurs dans les limites structurelles d'une page Postgres.
Bien que cette approche puisse conduire à des économies d'espace de stockage en raison de la compression de valeurs élevées spécifiques, son objectif principal n'est pas d'optimiser l'espace de stockage de manière générale.
Par exemple, si vous disposez d'une base de données de 5 To composée de petits tuples, TOAST ne vous aidera pas à transformer ces 5 To en 1 To. Bien que certains paramètres de TOAST puissent être ajustés, cela ne transformera pas TOAST en une solution généralisée d'économie de stockage.
Et il existe d'autres problèmes inhérents à l'utilisation de TOAST comme mécanisme de compression traditionnel dans PostgreSQL, par exemple :
L'accès aux données TOASTed peut ajouter une surcharge, en particulier lorsque les données sont stockées hors ligne. Cela devient plus évident lorsque de nombreux textes volumineux ou d'autres types de données compatibles TOAST sont fréquemment consultés.
TOAST ne dispose pas d'un mécanisme convivial de haut niveau pour dicter les politiques de compression. Il n'est pas conçu pour optimiser les coûts de stockage ou faciliter la gestion du stockage.
La compression de TOAST n'est pas conçue pour fournir des taux de compression particulièrement élevés. Il n'utilise qu'un seul algorithme ( pglz
) avec des taux de compression variant généralement de 25 à 50 %.
En ajoutant une politique de compression à vos grandes tables,
En définissant une politique de compression basée sur le temps, vous indiquez quand les données doivent être compressées. Par exemple, vous pouvez choisir de compresser automatiquement les données datant de plus de sept (7) jours :
-- Compress data older than 7 days SELECT add_compression_policy('my_hypertable', INTERVAL '7 days');
Via cette politique de compression, Timescale va transformer la table
Compression Gorilla pour flotteurs
Delta-de-delta +
Compression de dictionnaire sur une ligne entière pour les colonnes avec quelques valeurs répétitives (+ compression LZ en haut)
Compression de tableau basée sur LZ pour tous les autres types
Cette conception de compression en colonnes offre une solution efficace et évolutive au problème des grands ensembles de données dans PostgreSQL. Il vous permet d'utiliser moins de stockage pour stocker plus de données sans nuire aux performances de vos requêtes (cela les améliore). Et dans les dernières versions de TimescaleDB, vous pouvez également INSERT
, DELETE
et UPDATE
directement sur les données compressées.
Nous espérons que cet article vous a aidé à comprendre que même si TOAST est un mécanisme bien pensé pour gérer des valeurs volumineuses dans une page PostgreSQL, il n'est pas efficace pour optimiser l'utilisation du stockage de base de données dans le domaine des applications modernes.
Si vous recherchez une compression de données efficace qui peut faire avancer vos économies de stockage, essayez Timescale. Vous pouvez essayer notre plateforme cloud qui propulse PostgreSQL vers de nouveaux sommets de performances, le rendant plus rapide et plus puissant :
Écrit par Carlota Soto .