paint-brush
Postgres TOAST: Den Datenkomprimierungsmechanismus und seine Einschränkungen verstehenvon@timescale
6,869 Lesungen
6,869 Lesungen

Postgres TOAST: Den Datenkomprimierungsmechanismus und seine Einschränkungen verstehen

von Timescale11m2023/11/03
Read on Terminal Reader

Zu lang; Lesen

In diesem Artikel werden die Einschränkungen des TOAST-Mechanismus von PostgreSQL zur Datenkomprimierung erläutert, der ursprünglich für die Verwaltung großer Werte innerhalb einer PostgreSQL-Seite entwickelt wurde. Obwohl TOAST seine Vorzüge hat, ist es hinsichtlich der Optimierung der Speichereffizienz für moderne Anwendungen mit großen Datenmengen unzureichend. Der Artikel stellt die Spaltenkomprimierungsfunktion von TimescaleDB als Lösung vor, um die Datenbankgröße deutlich zu reduzieren und gleichzeitig die Abfrageleistung zu verbessern. Dieser Ansatz ermöglicht eine effizientere Speicherung und macht PostgreSQL zu einer besseren Wahl für die Datenverwaltung in modernen Anwendungen.
featured image - Postgres TOAST: Den Datenkomprimierungsmechanismus und seine Einschränkungen verstehen
Timescale HackerNoon profile picture


Wenn Sie mit großen Datenbanken in Postgres arbeiten, kommt Ihnen diese Geschichte bekannt vor. Wenn Ihre Postgres-Datenbank weiter wächst, beginnt Ihre Leistung zu sinken und Sie beginnen, sich Sorgen um den Speicherplatz zu machen – oder genauer gesagt, wie viel Sie dafür bezahlen werden. Sie lieben PostgreSQL, aber es gibt etwas, das Sie gerne hätten: einen hochwirksamen Datenkomprimierungsmechanismus.


PostgreSQL verfügt über einen Komprimierungsmechanismus: TOAST 🍞. In diesem Beitrag führen wir Sie durch die Funktionsweise von Postgres TOAST und die verschiedenen TOASTing-Strategien. So sehr wir einen guten TOAST genießen, werden wir diskutieren, warum dies nicht die Art von Komprimierungsfunktion ist, die Sie benötigen, um den Speicherbedarf moderner großer Datenbanken zu reduzieren – und wie wir als PostgreSQL-Enthusiasten, die wir hier bei Timescale sind, entschieden haben um einen geeigneteren Komprimierungsmechanismus für PostgreSQL zu entwickeln, inspiriert vom spaltenorientierten Design von NoSQL-Datenbanken.


Was ist Postgres-TOAST?

Auch wenn es die Größe von Datensätzen reduzieren könnte, ist TOAST (The Oversized Attribute Storage Technique) kein herkömmlicher Datenkomprimierungsmechanismus. Um zu verstehen, was TOAST ist, müssen wir zunächst darüber sprechen wie Daten in PostgreSQL gespeichert werden .


Die Speichereinheiten von Postgres werden Seiten genannt und haben eine feste Größe (standardmäßig 8 kB). Eine feste Seitengröße bietet Postgres viele Vorteile, nämlich die Einfachheit, Effizienz und Konsistenz der Datenverwaltung, hat aber auch einen Nachteil: Einige Datenwerte passen möglicherweise nicht auf diese Seite.


Hier kommt TOAST ins Spiel. TOAST bezieht sich auf den automatischen Mechanismus, den PostgreSQL verwendet, um Werte in Postgres, die nicht in eine Seite passen, effizient zu speichern und zu verwalten. Um solche Werte zu verarbeiten, komprimiert Postgres TOAST sie standardmäßig mithilfe eines internen Algorithmus. Wenn die Werte nach der Komprimierung immer noch zu groß sind, verschiebt Postgres sie in eine separate Tabelle (die so genannte TOAST-Tabelle), wobei die Zeiger in der Originaltabelle verbleiben.


Wie wir später in diesem Artikel sehen werden, können Sie diese Strategie als Benutzer tatsächlich ändern, indem Sie beispielsweise Postgres anweisen, die Komprimierung von Daten in einer bestimmten Spalte zu vermeiden.


TOAST-fähige Datentypen

Bei den Datentypen, die TOAST unterliegen könnten, handelt es sich in erster Linie um solche mit variabler Länge, die möglicherweise die Größenbeschränkungen einer Standard-PostgreSQL-Seite überschreiten. Andererseits unterliegen Datentypen fester Länge wie integer , float oder timestamp nicht TOAST, da sie problemlos in eine Seite passen.


Einige Beispiele für Datentypen, die TOAST unterliegen könnten, sind:


  • json und jsonb

  • Große text

  • varchar und varchar(n) (Wenn die in varchar(n) angegebene Länge klein genug ist, bleiben die Werte dieser Spalte möglicherweise immer unter dem TOAST-Schwellenwert.)

  • bytea Binärdaten speichert

  • Geometrische Daten wie path und polygon sowie PostGIS-Typen wie geometry oder geography


Wie funktioniert Postgres TOAST?

Das Verständnis von TOAST bezieht sich nicht nur auf das Konzept der Seitengröße, sondern auch auf ein anderes Postgres-Speicherkonzept: Tupel. Tupel sind Zeilen in einer PostgreSQL-Tabelle. Typischerweise greift der TOAST-Mechanismus, wenn alle Felder innerhalb eines Tupels eine Gesamtgröße von mehr als ca. 2 kB haben.


Wenn Sie aufgepasst haben, fragen Sie sich vielleicht: „Warten Sie, aber die Seitengröße beträgt etwa 8 kB – warum dieser Mehraufwand?“ Das liegt daran, dass PostgreSQL gerne sicherstellen möchte, dass mehrere Tupel auf einer einzelnen Seite gespeichert werden können: Wenn Tupel zu groß sind, passen weniger Tupel auf jede Seite, was zu mehr I/O-Vorgängen und einer geringeren Leistung führt.


Postgres muss außerdem freien Speicherplatz für zusätzliche Betriebsdaten vorhalten: Auf jeder Seite werden nicht nur die Tupeldaten, sondern auch zusätzliche Informationen zur Verwaltung der Daten gespeichert, z. B. Elementkennungen, Kopfzeilen und Transaktionsinformationen.


Wenn also die Gesamtgröße aller Felder in einem Tupel etwa 2 kB (oder den TOAST-Schwellenwertparameter, wie wir später sehen werden) überschreitet, ergreift PostgreSQL Maßnahmen, um sicherzustellen, dass die Daten effizient gespeichert werden. TOAST handhabt dies hauptsächlich auf zwei Arten:


  1. Kompression. PostgreSQL kann die großen Feldwerte innerhalb des Tupels komprimieren, um ihre Größe mithilfe eines Komprimierungsalgorithmus zu reduzieren, den wir später in diesem Artikel behandeln werden. Wenn die Komprimierung ausreicht, um die Gesamtgröße des Tupels unter den Schwellenwert zu bringen, bleiben die Daten standardmäßig in der Haupttabelle, wenn auch in einem komprimierten Format.


  2. Out-of-Line-Speicherung. Wenn die Komprimierung allein nicht effektiv genug ist, um die Größe der großen Feldwerte zu reduzieren, verschiebt Postgres sie in eine separate TOAST-Tabelle. Dieser Vorgang wird als „Out-of-Line“-Speicherung bezeichnet, da das ursprüngliche Tupel in der Haupttabelle die großen Feldwerte nicht mehr enthält. Stattdessen enthält es einen „Zeiger“ oder Verweis auf den Speicherort der großen Daten in der TOAST-Tabelle.


Wir vereinfachen die Dinge für diesen Artikel etwas: Lesen Sie die PostgreSQL-Dokumentation für eine vollständige Detailansicht.


Der Postgres-Komprimierungsalgorithmus: pglz

Wir haben erwähnt, dass TOAST große Werte in PostgreSQL komprimieren kann. Aber welchen Komprimierungsalgorithmus verwendet PostgreSQL und wie effektiv ist er?


pglz (PostgreSQL Lempel-Ziv) ist der standardmäßige interne Komprimierungsalgorithmus, der von PostgreSQL verwendet wird und speziell auf TOAST zugeschnitten ist.


So funktioniert es in ganz einfachen Worten:


  • pglz versucht, wiederholte Daten zu vermeiden. Wenn es wiederholte Daten sieht, schreibt es nicht dasselbe erneut, sondern verweist einfach auf die Stelle, an der es zuvor geschrieben wurde. Dieses „Vermeiden von Wiederholungen“ hilft, Platz zu sparen.


  • Während pglz Daten durchliest, merkt es sich einen Teil der zuletzt gesehenen Daten. Diese aktuelle Erinnerung wird als „gleitendes Fenster“ bezeichnet.


  • Wenn neue Daten eingehen, prüft pglz , ob es diese Daten kürzlich gesehen hat (innerhalb seines Schiebefensters). Wenn ja, wird eine kurze Referenz geschrieben, anstatt die Daten zu wiederholen.


  • Wenn die Daten neu sind oder nicht oft genug wiederholt werden, um eine Referenz kürzer als die tatsächlichen Daten zu machen, schreibt pglz sie einfach so auf, wie sie ist.


  • Wenn es Zeit ist, die komprimierten Daten zu lesen, verwendet pglz seine Referenzen, um die Originaldaten abzurufen. Dieser Vorgang ist recht direkt, da er die referenzierten Daten nachschlägt und dort ablegt, wo sie hingehören.


  • pglz benötigt keinen separaten Speicher für seinen Speicher (das Schiebefenster); Es baut es beim Komprimieren unterwegs auf und macht dasselbe beim Dekomprimieren.


Diese Implementierung soll ein Gleichgewicht zwischen Komprimierungseffizienz und Geschwindigkeit innerhalb des TOAST-Mechanismus bieten. In Bezug auf die Komprimierungsrate hängt die Wirksamkeit von pglz weitgehend von der Art der Daten ab.


Beispielsweise lassen sich stark repetitive Daten viel besser komprimieren als Daten mit hoher Entropie (z. B. Zufallsdaten). Sie sehen möglicherweise Komprimierungsverhältnisse im Bereich von 25 bis 50 Prozent, dies ist jedoch eine sehr allgemeine Schätzung – die Ergebnisse können je nach der genauen Art der Daten stark variieren.


TOAST konfigurieren

TOAST-Strategien

Standardmäßig durchläuft PostgreSQL den TOAST-Mechanismus gemäß dem zuvor erläuterten Verfahren (Komprimierung zuerst und dann Out-of-Line-Speicherung, wenn die Komprimierung nicht ausreicht). Dennoch kann es Szenarios geben, in denen Sie dieses Verhalten für jede einzelne Spalte optimieren möchten. PostgreSQL ermöglicht Ihnen dies durch die Verwendung der TOAST-Strategien PLAIN , EXTERNAL , EXTENDED und MAIN .


  • EXTENDED : Dies ist die Standardstrategie. Dies bedeutet, dass die Daten außerhalb der Zeile in einer separaten TOAST-Tabelle gespeichert werden, wenn sie für eine reguläre Tabellenseite zu groß sind. Bevor die Daten in die TOAST-Tabelle verschoben werden, werden sie komprimiert, um Platz zu sparen.


  • EXTERNAL : Diese Strategie weist PostgreSQL an, die Daten für diese Spalte außerhalb der Zeile zu speichern, wenn die Daten zu groß sind, um in eine reguläre Tabellenseite zu passen, und wir bitten PostgreSQL, die Daten nicht zu komprimieren – der Wert wird einfach in die verschoben TOAST-Tabelle im Ist-Zustand.


  • MAIN : Diese Strategie ist ein Mittelweg. Durch Komprimierung wird versucht, die Daten in der Haupttabelle in einer Reihe zu halten. Wenn die Daten definitiv zu groß sind, werden die Daten in die TOAST-Tabelle verschoben, um einen Fehler zu vermeiden, aber PostgreSQL verschiebt die komprimierten Daten nicht. Stattdessen wird der Wert in seiner ursprünglichen Form in der TOAST-Tabelle gespeichert.


  • PLAIN : Durch die Verwendung PLAIN in einer Spalte wird PostgreSQL angewiesen, die Daten der Spalte immer in einer Zeile in der Haupttabelle zu speichern, um sicherzustellen, dass sie nicht in eine Out-of-Line-TOAST-Tabelle verschoben werden. Bedenken Sie, dass der INSERT fehlschlägt, wenn die Daten die Seitengröße überschreiten, da die Daten nicht hineinpassen.


Wenn Sie die aktuellen Strategien einer bestimmten Tabelle überprüfen möchten, können Sie Folgendes ausführen:


 \d+ your_table_name


Sie erhalten eine Ausgabe wie diese:

 => \d+ example_table                     Table "public.example_table" Column |    Data Type  | Modifiers | Storage | Stats target | Description ---------+------------------+-----------+----------+--------------+-------------  bar  | varchar(100000) |      | extended |       |


Wenn Sie die Speichereinstellung ändern möchten, können Sie dies mit dem folgenden Befehl tun:

 -- Sets EXTENDED as the TOAST strategy for bar_column ALTER TABLE example_blob ALTER COLUMN bar_column SET STORAGE EXTENDED;

Schlüsselparameter

Neben den oben genannten Strategien sind auch diese beiden Parameter wichtig, um das TOAST-Verhalten zu steuern:


TOAST_TUPLE_THRESHOLD


Dies ist der Parameter, der den Größenschwellenwert festlegt, wenn TOASTing-Vorgänge (Komprimierung und Out-of-Line-Speicherung) für übergroße Tupel berücksichtigt werden.


Wie bereits erwähnt, ist TOAST_TUPLE_THRESHOLD standardmäßig auf etwa 2 kB eingestellt.


TOAST_COMPRESSION_THRESHOLD


Dies ist der Parameter, der die Mindestgröße eines Werts angibt, bevor Postgres eine Komprimierung während des TOASTing-Prozesses in Betracht zieht.


Wenn ein Wert diesen Schwellenwert überschreitet, versucht PostgreSQL, ihn zu komprimieren. Nur weil ein Wert über dem Komprimierungsschwellenwert liegt, heißt das nicht automatisch, dass er komprimiert wird: Die TOAST-Strategien leiten PostgreSQL an, wie mit den Daten umgegangen werden soll, basierend darauf, ob sie komprimiert wurden und wie groß sie im Verhältnis zum Tupel sind Seitenbegrenzungen, wie wir im nächsten Abschnitt sehen werden.


Alles zusammenbringen

TOAST_TUPLE_THRESHOLD ist der Triggerpunkt. Wenn die Größe der Datenfelder eines Tupels zusammen diesen Schwellenwert überschreitet, bewertet PostgreSQL, wie es auf der Grundlage der festgelegten TOAST-Strategie für seine Spalten verwaltet werden soll, wobei Komprimierung und Out-of-Line-Speicherung berücksichtigt werden. Die genauen Maßnahmen hängen auch davon ab, ob die Spaltendaten den TOAST_COMPRESSION_THRESHOLD überschreiten:


  • EXTENDED (Standardstrategie): Wenn die Größe eines Tupels TOAST_TUPLE_THRESHOLD überschreitet, versucht PostgreSQL zunächst, die übergroßen Spalten zu komprimieren, wenn sie auch TOAST_COMPRESSION_THRESHOLD überschreiten. Wenn die Tupelgröße durch Komprimierung unter den Schwellenwert sinkt, verbleibt sie in der Haupttabelle. Ist dies nicht der Fall, werden die Daten in eine Out-of-Line-TOAST-Tabelle verschoben und die Haupttabelle enthält Zeiger auf diese externen Daten.


  • MAIN : Wenn die Tupelgröße TOAST_TUPLE_THRESHOLD überschreitet, versucht PostgreSQL, die übergroßen Spalten zu komprimieren (vorausgesetzt, sie liegen über TOAST_COMPRESSION_THRESHOLD ). Wenn die Komprimierung es ermöglicht, dass das Tupel in das Tupel der Haupttabelle passt, bleibt es dort. Wenn nicht, werden die Daten in unkomprimierter Form in die TOAST-Tabelle verschoben.


  • EXTERNAL : PostgreSQL überspringt die Komprimierung, unabhängig von TOAST_COMPRESSION_THRESHOLD . Wenn die Größe des Tupels den TOAST_TUPLE_THRESHOLD überschreitet, werden die übergroßen Spalten außerhalb der Zeile in der TOAST-Tabelle gespeichert.


  • PLAIN : Daten werden immer in der Haupttabelle gespeichert. Wenn die Größe eines Tupels die Seitengröße überschreitet (aufgrund sehr großer Spalten), wird ein Fehler ausgelöst.


Strategie

Komprimieren, wenn Tupel > TOAST_COMPRESSION_THRESHOLD

Außerhalb der Linie speichern, wenn Tupel > TOAST_TUPLE_THRESHOLD

Beschreibung

ERWEITERT

Ja

Ja

Standardstrategie. Komprimiert zuerst und prüft dann, ob Out-of-Line-Speicher erforderlich ist.

HAUPTSÄCHLICH

Ja

Nur in unkomprimierter Form

Komprimiert zuerst, und wenn immer noch übergroß, wird es ohne Komprimierung in die TOAST-Tabelle verschoben.

EXTERNE

NEIN

Ja

Wechselt bei Übergröße immer zu TOAST, ohne Komprimierung.

SCHMUCKLOS

NEIN

NEIN

Die Daten bleiben immer in der Haupttabelle. Wenn ein Tupel die Seitengröße überschreitet, tritt ein Fehler auf.


Warum TOAST als Datenkomprimierungsmechanismus in PostgreSQL nicht ausreicht

Inzwischen werden Sie wahrscheinlich verstehen, warum TOAST nicht der Datenkomprimierungsmechanismus ist, den Sie sich in PostgreSQL gewünscht haben. Moderne Anwendungen erfordern täglich große Datenmengen, sodass Datenbanken schnell (über)wachsen.


Ein solches Problem war noch nicht so ausgeprägt, als unser geliebtes Postgres vor Jahrzehnten entwickelt wurde, aber heutige Entwickler benötigen Komprimierungslösungen, um den Speicherbedarf ihrer Datensätze zu reduzieren.


Obwohl TOAST die Komprimierung als eine seiner Techniken einbezieht, ist es wichtig zu verstehen, dass seine Hauptaufgabe nicht darin besteht, als Datenbankkomprimierungsmechanismus im herkömmlichen Sinne zu dienen. TOAST ist hauptsächlich eine Lösung für ein Problem: die Verwaltung großer Werte innerhalb der strukturellen Grenzen einer Postgres-Seite.


Während dieser Ansatz aufgrund der Komprimierung bestimmter großer Werte zu einer gewissen Speicherplatzeinsparung führen kann, besteht sein Hauptzweck nicht darin, den Speicherplatz auf breiter Front zu optimieren.


Wenn Sie beispielsweise eine 5-TB-Datenbank haben, die aus kleinen Tupeln besteht, hilft Ihnen TOAST nicht dabei, diese 5 TB in 1 TB umzuwandeln. Zwar gibt es innerhalb von TOAST Parameter, die angepasst werden können, doch dadurch wird TOAST nicht zu einer allgemeinen speichersparenden Lösung.


Und es gibt noch andere inhärente Probleme bei der Verwendung von TOAST als traditionellem Komprimierungsmechanismus in PostgreSQL, zum Beispiel:


  • Der Zugriff auf TOAST-Daten kann zu Mehraufwand führen, insbesondere wenn die Daten außerhalb der Zeile gespeichert werden. Dies wird deutlicher, wenn häufig auf viele große Texte oder andere TOAST-fähige Datentypen zugegriffen wird.


  • TOAST verfügt nicht über einen benutzerfreundlichen Mechanismus auf hoher Ebene zum Vorgeben von Komprimierungsrichtlinien. Es ist nicht darauf ausgelegt, Speicherkosten zu optimieren oder die Speicherverwaltung zu erleichtern.


  • Die Komprimierung von TOAST ist nicht darauf ausgelegt, besonders hohe Komprimierungsraten bereitzustellen. Es verwendet nur einen Algorithmus ( pglz ), wobei die Komprimierungsraten typischerweise zwischen 25 und 50 Prozent variieren.

Spaltenkomprimierung zu PostgreSQL mit Zeitskala hinzufügen

Über die TimescaleDB-Erweiterung , PostgreSQL-Benutzer haben eine bessere Alternative. Inspiriert durch das Komprimierungsdesign von NoSQL-Datenbanken, Wir haben PostgreSQL um eine spaltenorientierte Komprimierungsfunktion erweitert . Dieser transformative Ansatz geht über das herkömmliche zeilenbasierte Speicherparadigma von PostgreSQL hinaus und führt die Effizienz und Leistung der spaltenbasierten Speicherung ein.


Indem Sie Ihren großen Tabellen eine Komprimierungsrichtlinie hinzufügen, Sie können die Größe Ihrer PostgreSQL-Datenbank um das bis zu Zehnfache reduzieren (wodurch eine Komprimierungsrate von +90 Prozent erreicht wird). .


Durch die Definition einer zeitbasierten Komprimierungsrichtlinie geben Sie an, wann Daten komprimiert werden sollen. Beispielsweise können Sie Daten, die älter als sieben (7) Tage sind, automatisch komprimieren:


 -- Compress data older than 7 days SELECT add_compression_policy('my_hypertable', INTERVAL '7 days');


Über diese Komprimierungsrichtlinie transformiert Timescale die Tabelle Partitionen ( die in Timescale ebenfalls automatisch erstellt werden ) hinter den Kulissen in ein Spaltenformat umwandeln und dabei viele Zeilen (1.000) in einem Array kombinieren. Um die Komprimierbarkeit zu erhöhen, wendet Timescale je nach Datentyp unterschiedliche Komprimierungsalgorithmen an:


  • Gorilla-Kompression für Schwimmkörper

  • Delta-of-Delta + Einfach-8b mit Lauflängenkodierung Komprimierung für Zeitstempel und andere ganzzahlige Typen

  • Wörterbuchkomprimierung für ganze Zeilen für Spalten mit einigen sich wiederholenden Werten (+ LZ-Komprimierung oben)

  • LZ-basierte Array-Komprimierung für alle anderen Typen


Dieses spaltenorientierte Komprimierungsdesign bietet eine effiziente und skalierbare Lösung für das Problem großer Datensätze in PostgreSQL. Dadurch können Sie weniger Speicher verwenden, um mehr Daten zu speichern, ohne die Abfrageleistung zu beeinträchtigen (sie verbessert sich). Und in den neuesten Versionen von TimescaleDB können Sie INSERT , DELETE und UPDATE auch direkt über komprimierte Daten ausführen.

Einpacken

Wir hoffen, dieser Artikel hat Ihnen geholfen zu verstehen, dass TOAST zwar ein gut durchdachter Mechanismus zur Verwaltung großer Werte innerhalb einer PostgreSQL-Seite ist, sich jedoch nicht zur Optimierung der Datenbankspeichernutzung im Bereich moderner Anwendungen eignet.


Wenn Sie nach einer effektiven Datenkomprimierung suchen, die Ihre Speichereinsparungen deutlich steigern kann, probieren Sie Timescale aus. Sie können unsere Cloud-Plattform ausprobieren, die PostgreSQL zu neuen Leistungshöhen treibt und es schneller und leistungsfähiger macht – Es ist kostenlos und es ist keine Kreditkarte erforderlich – oder Sie können hinzufügen die TimescaleDB-Erweiterung zu Ihrer selbst gehosteten PostgreSQL-Datenbank.


Geschrieben von Carlota Soto .