Eine der interessanten Funktionen in PostgreSQL seit Version 9.4 ist die Möglichkeit, das Entfernen von WAL-Dateien mithilfe von Replikations-Slots zu steuern. Die dunkle Seite ist, dass Replikationsslots dazu führen können, dass Festplatten mit altem WAL gefüllt werden, wodurch der Hauptproduktionsserver zerstört wird. In diesem Artikel erkläre ich PostgreSQL-Replikationsslots und wie eine neue Funktion in PostgreSQL 13 dabei hilft, dieses Problem zu vermeiden.
WAL-Produktion
Wie Sie wissen, wird WAL für Datenbankänderungen auf einem primären Server erstellt:Einfügungen, Aktualisierungen, et cetera . Eine aktivere Datenbank produziert mehr WAL – auf einem sehr aktiven Server können jede Minute viele Gigabyte WAL produziert werden. WAL wird in Dateien mit Namen in aufsteigender numerischer Reihenfolge geschrieben, und die Dateien haben immer die gleiche Größe (16 MB ist Standard und typisch). Sobald die Daten in einer Datei nicht mehr benötigt werden, kann diese Datei recycelt werden , d. h. an eine höher nummerierte Position in der Sequenz umbenennen, damit sie später mit neuen Daten gefüllt werden kann.
(Es gibt besondere Situationen, wie z. B. einen Anstieg der Aktivität, der zur Erstellung zusätzlicher Dateien führt; wenn der Anstieg später nachlässt, werden diese zusätzlichen Dateien entfernt, anstatt wiederverwendet zu werden.)
Da alle Datenbank-Schreibaktivitäten WAL erzeugen, ist es wichtig, dass Festplattenspeicher verfügbar ist. Wenn die Festplatte, auf der WAL gespeichert ist, voll ist, kann der Server keine neuen Transaktionen verarbeiten und kann hängen bleiben oder schlimmer noch:er kann vollständig umfallen. Dies ist also eine Situation, die mit allen Mitteln vermieden werden sollte.
Replikationsslots
Die Replikation in PostgreSQL funktioniert durch die Verarbeitung von WAL-Dateien. Damit dies funktioniert, müssen alle WAL-Dateien vorübergehend verfügbar sein, bis sie verarbeitet werden. Daher wird ein Mechanismus benötigt, um dem Haupt-WAL-Management mitzuteilen, Dateien nicht zu recyceln oder zu entfernen.
Geben Sie Replikationsslots ein. Slots sind ein Mechanismus, der darauf hinweist, dass dies Backup, das wir machen, erfordert das WAL-Datei, und können Sie sie bitte noch nicht löschen; oder dies Replikat hat das immer noch nicht verarbeitet WAL-Datei, also kann sie bitte eine Weile in Ruhe gelassen werden.
Replikationsslots belegen an sich nur sehr wenig Speicherplatz. Sie speichern nur winzige Metadaten, einschließlich eines Zeigers auf eine Position in WAL. Aber die WAL-Daten, die es schützt, sind eine andere Sache:Auf einem hochaktiven Server können sie in Gigabyte oder schlimmer gemessen werden.
WAL-Verbrauch
Das Zuführen von Daten zu einem physischen Replikat bedeutet, dass die WAL-Daten von seinem primären Server kopiert werden. In ähnlicher Weise muss ein logisches Replikat WAL-Daten lesen (und eine interpretierte Version an das Replikat übertragen). Die gelesene WAL-Position ist das, was der Schlitz verfolgt. Sobald das Replikat die WAL-Daten irgendwie gesichert hat, kann der Slot erweitert werden; dies teilt der WAL-Verwaltung in der Primärdatenbank mit, dass die WAL-Datei dann zum Entfernen verfügbar ist. Dies geschieht kontinuierlich, wenn das Replikat aktiv ist, sodass WAL auf dem primären Server die gleiche Menge an Speicherplatz oder vielleicht nur etwas mehr belegt. Je nach Bedingungen kann sogar das Doppelte oder Zehnfache akzeptabel sein.
Das Problem ist, dass, wenn ein Replikat vollständig stirbt und sich über einen längeren Zeitraum nicht erholt; oder die Replik wird zerstört und der DBA vergisst, den Replikationsslot zu entfernen; oder der Schlitz ist ein vergessenes Überbleibsel eines Experiments; oder sogar das Replikat wird über eine langsame Netzwerkverbindung gespeist, dann wächst die reservierte WAL ins Unermessliche. Und das wird zur tickenden Bombe.
Slot-Größe begrenzen
Um dieses Problem zu bekämpfen, arbeitete Kyotaro Horiguchi seit Februar 2017 an einem PostgreSQL-Patch, um die Größe der von einem Slot reservierten WAL zu begrenzen. Nach einem sehr langen Überprüfungs- und Überarbeitungsprozess habe ich es für PostgreSQL 13 integriert, um die Verwaltung von PostgreSQL-Farmen mit hoher Verfügbarkeit zu verbessern.
Das Hauptprinzip ist, dass es besser ist, ein Replikat zu töten (indem man seinen Steckplatz irgendwie ungültig macht; mehr dazu weiter unten), als den primären Server zu töten, der dieses Replikat speist, und die gesamte Produktion damit zunichte zu machen.
Die Funktionsweise ist ziemlich einfach:setze max_slot_wal_keep_size
(Dokumentation) in postgresql.conf auf die maximale Menge an Speicherplatz von WAL, die Replikationsslots reservieren dürfen. Wenn ein Slot diesen Punkt erreicht und ein Prüfpunkt auftritt, wird dieser Slot als ungültig markiert und einige WAL-Dateien können gelöscht werden. Wenn der Slot von einem Walsender aktiv genutzt wurde Prozess, wird diesem Prozess signalisiert, dass er beendet wird. Wenn der Walsender erneut startet, stellt er fest, dass die erforderlichen WAL-Dateien nicht mehr vorhanden sind. Das Replikat, das diesen Steckplatz verwendet, muss neu geklont werden.
Wenn max_slot_wal_keep_size
Null ist, was der Standardwert ist, dann gibt es keine Begrenzung. Ich empfehle dies nicht, da es zu Fehlern führt, wenn Slots die Festplatte füllen.
Slot-Zustand überwachen
Ebenfalls enthalten sind einige Überwachungsfunktionen. Zwei Spalten in pg_replication_slots sind relevant. Der kritischste ist wal_status
. Wenn diese Spalte reserved
ist , dann zeigt der Slot auf Daten innerhalb von max_wal_size
; wenn es extended
ist dann wurde max_wal_size
überschritten , ist aber weiterhin entweder durch wal_keep_size
geschützt oder max_slot_wal_keep_size
(auch wenn max_slot_wal_keep_size
ist null). Jeder Zustand ist gut und normal. Wenn jedoch ein Slot das Limit überschreitet, wird er zunächst unreserved
, was bedeutet, dass es in unmittelbarer Gefahr ist, sich aber immer noch erholen kann, wenn es schnell genug ist. Schließlich wird der Status zu lost
wenn WAL-Dateien entfernt wurden und keine Wiederherstellung möglich ist.
Die andere Spalte ist safe_wal_size
:Es zeigt die Anzahl der WAL-Bytes an, die geschrieben werden können, bevor dieser Steckplatz in Gefahr gerät, dass WAL-Dateien entfernt werden. Wir empfehlen, diese Spalte in Ihrem Überwachungssystem genau im Auge zu behalten und Alarm zu schlagen, wenn sie niedrig wird. Null oder negativ bedeutet, dass Ihr Replikat tot ist, sobald ein Kontrollpunkt auftritt:
SELECT slot_name, active, wal_status, safe_wal_size FROM pg_catalog.pg_replication_slots;
Wir glauben, dass diese neue Funktion die Wartung von Replikaten einfacher und robuster macht; hoffentlich sehen wir wegen dieser Probleme keine weiteren Katastrophen mit Produktionsausfällen.
(Ein Hinweis:safe_wal_size
wurde in 13beta3 eingeführt, also konsultieren Sie unbedingt die aktuelle Dokumentation, oder Sie sehen min_safe_lsn
stattdessen. Ignoriere das.)
Danke
Besonderer Dank geht an Kyotaro Horiguchi für die Arbeit an der Lösung dieses Problems. Mehrere Rezensenten haben sich intensiv damit befasst, unter denen ich besonders Masahiko Sawada, Fujii Masao, Jehan-Guillaume de Rorthais und Amit Kapila (in keiner bestimmten Reihenfolge) danken möchte.