paint-brush
Postgres TOAST : Comprendre le mécanisme de compression des données et ses limitespar@timescale
7,544 lectures
7,544 lectures

Postgres TOAST : Comprendre le mécanisme de compression des données et ses limites

par Timescale11m2023/11/03
Read on Terminal Reader

Trop long; Pour lire

Cet article traite des limites du mécanisme TOAST de PostgreSQL pour la compression des données, conçu à l'origine pour gérer des valeurs volumineuses dans une page PostgreSQL. Bien que TOAST ait ses mérites, il ne parvient pas à optimiser l'efficacité du stockage pour les applications modernes avec de grands ensembles de données. L'article présente la fonctionnalité de compression en colonnes de TimescaleDB comme solution permettant de réduire considérablement la taille de la base de données tout en améliorant les performances des requêtes. Cette approche permet un stockage plus efficace, faisant de PostgreSQL un choix plus formidable pour la gestion des données dans les applications contemporaines.
featured image - Postgres TOAST : Comprendre le mécanisme de compression des données et ses limites
Timescale HackerNoon profile picture


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 : GRILLER 🍞. Dans cet article, nous vous expliquerons le fonctionnement de Postgres TOAST et les différentes stratégies TOASTing. Même si nous apprécions un bon TOAST, nous expliquerons pourquoi ce n'est pas le type de fonctionnalité de compression dont vous avez besoin pour réduire l'empreinte de stockage des grandes bases de données modernes - et comment, en tant que passionnés de PostgreSQL que nous sommes ici chez Timescale, nous avons décidé pour construire un mécanisme de compression plus adapté à PostgreSQL, inspiré de la conception en colonnes des bases de données NoSQL.


Qu’est-ce que Postgres TOAST ?

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 comment les données sont stockées dans PostgreSQL .


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.


Types de données compatibles TOAST

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


Comment fonctionne Postgres TOAST ?

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 :


  1. 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é.


  2. 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— lisez la documentation PostgreSQL pour une vue détaillée complète.


L'algorithme de compression Postgres : 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.


Configuration de TOAST

Stratégies TOAST

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;

Paramètres clés

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.


Rassembler tout cela

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.


Pourquoi TOAST n'est pas suffisant en tant que mécanisme de compression de données dans PostgreSQL

À 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 %.

Ajout d'une compression en colonnes à PostgreSQL avec une échelle de temps

Via l'extension TimescaleDB , les utilisateurs de PostgreSQL disposent d'une meilleure alternative. Inspiré par la conception de compression des bases de données NoSQL, nous avons ajouté une fonctionnalité de compression en colonnes à PostgreSQL . Cette approche transformatrice transcende le paradigme conventionnel de stockage basé sur les lignes de PostgreSQL, introduisant l'efficacité et les performances du stockage en colonnes.


En ajoutant une politique de compression à vos grandes tables, vous pouvez réduire la taille de votre base de données PostgreSQL jusqu'à 10 fois (atteignant des taux de compression de +90 %) .


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 cloisons ( qui dans Timescale sont également créés automatiquement ) dans un format en colonnes en arrière-plan, combinant plusieurs lignes (1 000) dans un tableau. Pour augmenter la compressibilité, Timescale appliquera différents algorithmes de compression en fonction du type de données :


  • Compression Gorilla pour flotteurs

  • Delta-de-delta + Simple-8b avec codage en longueur compression pour les horodatages et autres types de type entier

  • 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.

Conclure

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 : c'est gratuit et aucune carte de crédit n'est requise -ou vous pouvez ajouter l'extension TimescaleDB à votre base de données PostgreSQL auto-hébergée.


Écrit par Carlota Soto .