PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Best-Practice-Tipps für PostgreSQL VACUUM und ANALYZE

VACUUM und ANALYZE sind die beiden wichtigsten Wartungsvorgänge für die PostgreSQL-Datenbank.

Ein Vakuum wird verwendet, um den von „toten Tupeln“ belegten Platz in einer Tabelle zurückzugewinnen. Ein totes Tupel wird erstellt, wenn ein Datensatz entweder gelöscht oder aktualisiert wird (ein Löschen gefolgt von einem Einfügen). PostgreSQL entfernt die alte Zeile nicht physisch aus der Tabelle, sondern setzt eine „Markierung“ darauf, damit Abfragen diese Zeile nicht zurückgeben. Wenn ein Vakuumprozess ausgeführt wird, wird der von diesen toten Tupeln belegte Speicherplatz als wiederverwendbar durch andere Tupel markiert.

Eine „Analyse“-Operation tut, was ihr Name sagt – sie analysiert den Inhalt der Tabellen einer Datenbank und sammelt Statistiken über die Verteilung der Werte in jeder Spalte jeder Tabelle. Die PostgreSQL-Abfrage-Engine verwendet diese Statistiken, um den besten Abfrageplan zu finden. Wenn Zeilen in einer Datenbank eingefügt, gelöscht und aktualisiert werden, ändern sich auch die Spaltenstatistiken. ANALYZE – entweder manuell vom DBA oder automatisch von PostgreSQL nach einer Selbstbereinigung ausgeführt – stellt sicher, dass die Statistiken auf dem neuesten Stand sind.

Obwohl sie relativ einfach klingen, sind Staubsaugen und Analysieren hinter den Kulissen zwei komplexe Prozesse. Glücklicherweise müssen sich DBAs nicht viel um ihre Interna kümmern. Sie sind jedoch oft verwirrt, wenn es darum geht, diese Prozesse manuell auszuführen oder die optimalen Werte für die Konfigurationsparameter festzulegen.

In diesem Artikel stellen wir einige Best Practices für VACUUM und ANALYZE vor.

Tipp 1:Führen Sie manuelles VAKUUMIEREN oder ANALYSIEREN nicht ohne Grund durch

PostgreSQL-Bereinigung (Autovacuum oder manuelle Bereinigung) minimiert Tabellenaufblähungen und verhindert Transaktions-ID-Wraparound. Autovacuum stellt den von toten Tupeln belegten Speicherplatz nicht wieder her. Allerdings wird ein VAKUUM VOLL ausgeführt Befehl wird dies tun. VACUUM FULL hat jedoch seine Auswirkungen auf die Leistung. Die Zieltabelle wird während des Vorgangs exklusiv gesperrt, wodurch sogar Lesezugriffe auf die Tabelle verhindert werden. Der Prozess erstellt auch eine vollständige Kopie der Tabelle, was zusätzlichen Speicherplatz benötigt, wenn er ausgeführt wird. Wir empfehlen, VACUUM FULL nicht auszuführen, es sei denn, es gibt einen sehr hohen Prozentsatz an Aufblähung und Abfragen leiden stark darunter. Wir empfehlen auch, Zeiträume mit der geringsten Datenbankaktivität dafür zu verwenden.

Es ist auch eine bewährte Methode, manuelle Bereinigungen nicht zu oft auf der gesamten Datenbank auszuführen; die Zieldatenbank konnte durch den Autovacuum-Prozess bereits optimal evakuiert werden. Infolgedessen entfernt eine manuelle Bereinigung möglicherweise keine toten Tupel, verursacht jedoch unnötige E/A-Lasten oder CPU-Spitzen. Bei Bedarf sollten manuelle Bereinigungen nur dann tischweise ausgeführt werden, wenn dies erforderlich ist, z. B. bei niedrigen Verhältnissen von aktiven Reihen zu toten Reihen oder großen Lücken zwischen automatischen Bereinigungen. Außerdem sollten manuelle Bereinigungen ausgeführt werden, wenn die Benutzeraktivität minimal ist.

Autovacuum hält auch die Datenverteilungsstatistiken einer Tabelle auf dem neuesten Stand (es baut sie nicht neu auf). Bei manueller Ausführung wird die ANALYSE Der Befehl erstellt diese Statistiken tatsächlich neu, anstatt sie zu aktualisieren. Auch hier kann das erneute Erstellen von Statistiken, wenn sie bereits optimal durch eine regelmäßige Autovakuum aktualisiert wurden, zu einer unnötigen Belastung der Systemressourcen führen.

Der Zeitpunkt, zu dem Sie ANALYZE manuell ausführen müssen, ist unmittelbar nach dem Massenladen von Daten in die Zieltabelle. Eine große Anzahl (sogar einige hundert) neuer Zeilen in einer vorhandenen Tabelle wird die Spaltendatenverteilung erheblich verzerren. Die neuen Zeilen führen dazu, dass alle vorhandenen Spaltenstatistiken veraltet sind. Wenn der Abfrageoptimierer solche Statistiken verwendet, kann die Abfrageleistung sehr langsam sein. In diesen Fällen ist es besser, den ANALYZE-Befehl unmittelbar nach dem Laden der Daten auszuführen, um die Statistiken vollständig neu zu erstellen, als darauf zu warten, dass die Selbstbereinigung einsetzt.

Tipp 2:Feinabstimmung des Autovakuum-Schwellenwerts

Es ist wichtig, das Autovacuum zu überprüfen oder abzustimmen und die Konfigurationsparameter in der postgresql.conf zu analysieren Datei oder in einzelnen Tabelleneigenschaften, um ein Gleichgewicht zwischen Selbstbereinigung und Leistungssteigerung zu finden.

PostgreSQL verwendet zwei Konfigurationsparameter, um zu entscheiden, wann eine Selbstbereinigung gestartet werden soll:

  • autovacuum_vacuum_threshold :Dies hat einen Standardwert von 50
  • autovacuum_vacuum_scale_factor :Dies hat einen Standardwert von 0,2

Zusammen weisen diese Parameter PostgreSQL an, eine Selbstbereinigung zu starten, wenn die Anzahl der toten Zeilen in einer Tabelle die Anzahl der Zeilen in dieser Tabelle multipliziert mit dem Skalierungsfaktor plus dem Vakuumschwellenwert überschreitet. Mit anderen Worten, PostgreSQL startet die Selbstbereinigung einer Tabelle, wenn:

pg_stat_user_tables.n_dead_tup > (pg_class.reltuples x autovacuum_vacuum_scale_factor)  + autovacuum_vacuum_threshold

Für kleine bis mittelgroße Tische kann dies ausreichend sein. Beispiel:Bei einer Tabelle mit 10.000 Zeilen muss die Anzahl der toten Zeilen über 2.050 ((10.000 x 0,2) + 50) liegen, bevor ein Autovacuum beginnt.

Nicht jede Tabelle in einer Datenbank erfährt die gleiche Datenänderungsrate. Normalerweise erfahren einige große Tabellen häufige Datenänderungen und weisen daher eine höhere Anzahl toter Zeilen auf. Die Standardwerte funktionieren für solche Tabellen möglicherweise nicht. Beispielsweise muss eine Tabelle mit 1 Million Zeilen mit den Standardwerten mehr als 200.050 tote Zeilen aufweisen, bevor eine Selbstbereinigung beginnt ((1000.000 x 0,2) + 50). Dies kann längere Lücken zwischen Autovacuums, immer längere Autovacuum-Zeiten und schlimmer noch bedeuten, dass Autovacuum überhaupt nicht ausgeführt wird, wenn aktive Transaktionen auf der Tabelle sie sperren.

Daher sollte das Ziel darin bestehen, diese Schwellenwerte auf optimale Werte festzulegen, damit die Selbstbereinigung in regelmäßigen Abständen erfolgen kann und nicht lange dauert (und Benutzersitzungen beeinträchtigt), während die Anzahl toter Zeilen relativ gering bleibt.

Ein Ansatz besteht darin, den einen oder anderen Parameter zu verwenden. Wenn wir also autovacuum_vacuum_scale_factor auf 0 und stattdessen autovacuum_vacuum_threshold beispielsweise auf 5.000 setzen, wird eine Tabelle automatisch evakuiert, wenn die Anzahl der toten Zeilen mehr als 5.000 beträgt.

Tipp 3:Passen Sie den Autoanalyse-Schwellenwert an

Ähnlich wie beim Autovacuum verwendet die Autoanalyse auch zwei Parameter, die entscheiden, wann das Autovacuum ebenfalls eine Autoanalyse auslöst:

  • autovacuum_analyze_threshold :Dies hat einen Standardwert von 50
  • autovacuum_analyze_scale_factor :Dies hat einen Standardwert von 0,1

Wie Autovacuum kann der Parameter autovacuum_analyze_threshold auf einen Wert gesetzt werden, der die Anzahl der eingefügten, gelöschten oder aktualisierten Tupel in einer Tabelle vorgibt, bevor eine automatische Analyse beginnt. Wir empfehlen, diesen Parameter für große und transaktionsreiche Tabellen separat festzulegen. Die Tabellenkonfiguration überschreibt die postgresql.conf-Werte.

Das folgende Code-Snippet zeigt die SQL-Syntax zum Ändern der Einstellung autovacuum_analyze_threshold für eine Tabelle.

ALTER TABLE <table_name> 
SET (autovacuum_analyze_threshold = <threshold rows>)

Tipp 4:Feinabstimmung der Autovacuum Worker

Ein weiterer Parameter, der von DBAs oft übersehen wird, ist autovacuum_max_workers , der einen Standardwert von 3 hat. Autovacuum ist kein einzelner Prozess, sondern eine Reihe einzelner Vakuum-Threads, die parallel ausgeführt werden. Der Grund für die Angabe mehrerer Worker besteht darin, sicherzustellen, dass das Vakuumieren großer Tabellen das Vakuumieren kleinerer Tabellen und Benutzersitzungen nicht aufhält. Der Parameter autovacuum_max_workers weist PostgreSQL an, die Anzahl der Autovacuum-Worker-Threads zu erhöhen, um die Bereinigung durchzuführen.

Eine gängige Praxis von PostgreSQL-DBAs besteht darin, die Anzahl der maximalen Worker-Threads zu erhöhen, in der Hoffnung, dass dadurch die Selbstbereinigung beschleunigt wird. Dies funktioniert nicht, da alle Threads dasselbe autovacuum_vacuum_cost_limit teilen , der einen Standardwert von 200 hat. Jedem Autovacuum-Thread wird mithilfe der folgenden Formel ein Kostenlimit zugewiesen:

individual thread’s cost_limit = autovacuum_vacuum_cost_limit / autovacuum_max_workers

Die Arbeitskosten eines Autovacuum-Threads werden anhand von drei Parametern berechnet:

  • vacuum_cost_page_hit :Dies hat einen Standardwert von 1
  • vacuum_cost_page_miss :Dies hat einen Standardwert von 10
  • vacuum_cost_page_dirty :Dies hat einen Standardwert von 20

Diese Parameter bedeuten Folgendes:

  • Wenn ein Vakuum-Thread die Datenseite findet, die er im gemeinsam genutzten Puffer bereinigen soll, betragen die Kosten 1. 
  • Wenn sich die Datenseite nicht im gemeinsam genutzten Puffer, sondern im Betriebssystem-Cache befindet, betragen die Kosten 10 . 
  • Muss die Seite als schmutzig markiert werden, weil der Vakuum-Thread tote Zeilen löschen musste, betragen die Kosten 20.

Eine erhöhte Anzahl von Worker-Threads senkt die Kostengrenze für jeden Thread. Da jedem Thread eine niedrigere Kostengrenze zugewiesen wird, wird er häufiger schlafen gehen, wenn die Kostenschwelle leicht erreicht wird, was letztendlich dazu führt, dass der gesamte Vakuumprozess langsam abläuft. Wir empfehlen, das autovacuum_vacuum_cost_limit auf einen höheren Wert zu erhöhen, z. B. 2000, und dann die maximale Anzahl von Worker-Threads anzupassen.

Eine bessere Möglichkeit besteht darin, diese Parameter nur bei Bedarf für einzelne Tabellen zu optimieren. Wenn beispielsweise das Autovacuum einer großen Transaktionstabelle zu lange dauert, kann die Tabelle vorübergehend so konfiguriert werden, dass sie ihr eigenes Vakuumkostenlimit und Kostenverzögerungen verwendet. Das Kostenlimit und die Verzögerung überschreiben die systemweiten Werte, die in postgresql.conf festgelegt sind.

Das folgende Code-Snippet zeigt, wie einzelne Tabellen konfiguriert werden.

ALTER TABLE <table_name> SET (autovacuum_vacuum_cost_limit = <large_value>)
ALTER TABLE <table_name> SET (autovacuum_vacuum_cost_delay = <lower_cost_delay>)

Durch die Verwendung des ersten Parameters wird sichergestellt, dass der der Tabelle zugewiesene Autovacuum-Thread mehr Arbeit ausführt, bevor er in den Ruhezustand wechselt. Verringern der autovacuum_vacuum_cost_delay bedeutet auch, dass der Thread weniger Zeit schläft.

Abschließende Gedanken

Wie Sie sehen können, ist das Ändern der Konfigurationsparameter für Vakuum und Analyse unkompliziert, erfordert jedoch zunächst eine sorgfältige Beobachtung. Jede Datenbank unterscheidet sich in Bezug auf Größe, Verkehrsmuster und Transaktionsrate. Wir empfehlen DBAs, zunächst genügend Informationen über ihre Datenbank zu sammeln, bevor sie die Parameter ändern oder ein manuelles Vakuum-/Analyseregime einführen. Solche Informationen könnten sein:

  • Anzahl der Zeilen in jeder Tabelle
  • Anzahl toter Tupel in jeder Tabelle
  • Die Zeit des letzten Vakuums für jeden Tisch
  • Der Zeitpunkt der letzten Analyse für jede Tabelle
  • Die Rate des Einfügens/Aktualisierens/Löschens von Daten in jeder Tabelle
  • Die Zeit, die das Autovacuum für jede Tabelle benötigt
  • Warnungen, dass Tische nicht gesaugt werden
  • Aktuelle Leistung der wichtigsten Abfragen und der Tabellen, auf die sie zugreifen
  • Leistung der gleichen Abfragen nach einer manuellen Bereinigung/Analyse

Von hier aus können DBAs einige „Pilot“-Tabellen auswählen, um mit der Optimierung zu beginnen. Sie können damit beginnen, die Vakuum-/Analyseeigenschaften für die Tische zu ändern und die Leistung zu überprüfen. PostgreSQL ist eine intelligente Datenbank-Engine – DBAs werden oft feststellen, dass es wahrscheinlich am besten ist, PostgreSQL das Staubsaugen und Analysieren zu überlassen, anstatt dies manuell zu tun.