
In PostgreSQL wurde seit sehr alten Zeiten
bereits Version 8.0, die bereits 2005 veröffentlicht wurde, eine spezielle
Konfigurationsdatei recovery.conf verwendet, um zu einem bestimmten Zeitpunkt wiederherzustellen. Dieselbe Datei wurde später für den Standby-Modus und die Streaming-Replikation verwendet.
Seit der nächsten Version von PostgreSQL 12 funktioniert die Datei recovery.conf jedoch nicht mehr: Ich habe sie kaputt gemacht.
Aber warum?
Recovery.conf hatte eine Funktion: Es wurde nur zu Beginn des DBMS gelesen. Wenn die Wiederherstellung zu einem bestimmten Zeitpunkt, die weniger als einmal im Jahr erforderlich ist, immer noch abgeglichen werden kann, ist die Notwendigkeit, die gesamte Datenbank neu zu starten, um die Adresse des Upstream-Replikationsservers zu ändern, etwas bedrückend. Ich habe verschiedene Arten von Perversionen gesehen, um diese Einschränkung zu umgehen, z. B. die Verwendung von L3-Routing, die Kaskadierung von Replikationsschemata (so dass nicht alle Replikate, aber zumindest nur ein Teil davon) und sogar
Walbouncer (auch wenn ich sie in der Produktion nicht gesehen habe).
Nach dem nächsten geplanten Neustart der Replikate habe ich mich entschlossen, die Replikationsparameter zu ändern, aber was würde es kosten, PostgreSQL das erneute Lesen von primary_conninfo in SIGHUP beizubringen?
Alles ist schlecht gelaufen. Im Prinzip müssen Sie im Startvorgang nur eine Variable ändern und von dort aus einen Neustart von WalReceiver anfordern. Damit wird die Replikation mit der neuen Adresse korrekt fortgesetzt. Es bleibt, dies korrekt umzusetzen. Einige Wochen später beendete ich den Patch mit der Implementierung des erneuten Lesens von recovery.conf für das SIGHUP-Signal, während dieser Patch das vorhandene Datenbankverhalten nicht beeinträchtigte.
Dann
schickte er ihn mit Mut zur PostgreSQL-Entwickler-Mailingliste. Was Michael Paquier ziemlich schnell antwortete:
Bevor Sie einige davon als nachladbar festlegen, sollten Sie sie zuerst auf GUCs umstellen und die SIGHUP-Behandlung von Parametern nicht wie in Ihrem Patch neu erfinden.
Hoppla, es stellte sich heraus, dass ich der Suchmaschine die falsche Frage gestellt habe. Die Frage betraf nicht das erneute Lesen der Datei recovery.conf, sondern die Konvertierung von Parametern aus einer separaten Datei recovery.conf in die GUC-Infrastruktur (Grand Unified Configuration), die für alle anderen DBMS-Parameter verwendet wird. Das heißt definitiv nicht, wir brauchen keinen solchen Patch, wir wollen das nicht. Übertragen wir zunächst alle diese Einstellungen von recovery.conf in unsere Standardeinstellungsinfrastruktur.
In diesen düsteren Nachrichten verbrannte ich und dachte: "Aber lasst uns übertragen!". Ich habe die archivierten Diskussionen über die richtige Suchabfrage gelesen und die letzte
Diskussion zum Übertragen von Einstellungen geöffnet (der Link wurde freundlicherweise von Michael Paquier in seiner Antwort bereitgestellt, für die ich ihm separat danke, sowie für die schnelle Antwort). Zu diesem Zeitpunkt, im Mai 2018, wurde der Patch für mehr als ein Jahr aufgegeben. Also, hier fangen wir an. Oder ist es richtiger, „weiter“ zu sagen? Nach dem Unterhaltungsplan:
- Lesen und Auflisten von Änderungen an der neuesten veröffentlichten Version des Patches
- Analysieren Sie die Änderungen im Patch und übertragen Sie die erforderlichen Änderungen auf die aktuelle Version der Codebasis
- Korrigieren Sie alle Verweise auf recovery.conf und seine Parameter in der Dokumentation
- Reparaturtests
- Senden Sie einen neuen Patch an die Mailingliste
- Feedback bekommen
- etwas nach den Wünschen zu korrigieren und zu Absatz 5 zurückzukehren
- eine Weigerung zu erhalten, den Patch erneut anzunehmen (in anderthalb Jahren)
Klingt nach einem Aktionsplan? Nun, hier machen wir weiter!
Wie lange, kurz, habe ich Punkt fünf erreicht und am 21. Juni 2018 eine neue Version des Patches
in einem neuen Diskussionsthread veröffentlicht . Dann 3 Monate in der bedrückenden Stille der kühlen Stille der Baskervilles-Fische. Ende September zeigte Peter Eisentraut, einer der Core-Entwickler mit dem Recht auf Commit, plötzlich Interesse an dem Patch. Nach mehreren Iterationen von Korrekturen, während ich ein paar Tage lang leise wegging, um Budapest zu besichtigen und die Sehenswürdigkeiten zu besichtigen, kommt ein entmutigender Brief von Peter Eisentraut:
Ich ging den Patch durch und nahm ein paar kleine Verbesserungen vor. Ich habe auch die Dokumentation ausführlicher aktualisiert. Der angehängte Patch ist für mich verbindlich.
Das heißt, Peter Eisentraut hat nach eigenem Ermessen weitere Kleinigkeiten korrigiert, die Dokumentation aktualisiert, den gesamten Abschnitt recovery-config.sgml gebrannt und ist der Ansicht, dass der Patch in dieser Form bereits akzeptiert werden kann. Oh, und ich dachte, es würde nur für Postgresql 13 passieren, auch wenn es so glücklich ist, dass der Patch im Allgemeinen einen Bereitschaftszustand für das Festschreiben erreicht.
Und ein paar Tage später, nämlich am 25. November 2018,
akzeptiert Peter Eisentraut
diesen Patch wirklich:
Die Einstellungen für recovery.conf werden jetzt in postgresql.conf (oder anderen GUC-Quellen) festgelegt. Derzeit sind alle betroffenen Einstellungen PGC_POSTMASTER. Dies könnte in Zukunft von Fall zu Fall verfeinert werden.
Die Wiederherstellung wird jetzt durch eine Datei recovery.signal initiiert. Der Standby-Modus wird durch eine Datei standby.signal ausgelöst. Die Standby-Modus-Einstellung ist weg. Wenn eine Datei recovery.conf gefunden wird, wird ein Fehler ausgegeben.
Die Einstellung trigger_file wurde im Rahmen des Verschiebens in boost_trigger_file umbenannt.
Das Dokumentationskapitel "Wiederherstellungskonfiguration" wurde in "Serverkonfiguration" integriert.
pg_basebackup -R hängt jetzt Einstellungen an postgresql.auto.conf an und erstellt eine standby.signal-Datei.
Autor: Fujii Masao <masao (Punkt) fujii (at) gmail (Punkt) com>
Autor: Simon Riggs <simon (at) 2ndquadrant (dot) com>
Autor: Abhijit Menon-Sen <ams (at) 2ndquadrant (dot) com>
Autor: Sergei Kornilov <sk (at) zsrv (dot) org>
Zwei Wochen sind vergangen und dieses Commit wurde nicht zurückgesetzt. Erstaunlich Und es scheint, dass sie es nicht einmal tun werden. Es ist erstaunlich. Es ist nicht bekannt, ob die Community beschließen wird, das Verhalten erneut in eine Richtung zu ändern, zumal es noch einige Zeit dauert, bis Postgresql 12 im April veröffentlicht wird. Aber es scheint, dass wir nicht mehr recovery.conf haben werden.
Was hat sich also geändert?
In erster Linie wird das DBMS den Start verweigern, wenn es eine Datei recovery.conf findet. Dies wurde speziell durchgeführt, damit der Benutzer, der eine der vielen alten Anweisungen verwendet, nicht überrascht ist, warum die Datenbank die Konfiguration in dieser Datei ignoriert.
Die alte Standby-Modus-Einstellung ist weg. Jetzt wird es ebenso wie die Tatsache, dass die Datei recovery.conf vorhanden ist, um den Wiederherstellungsmodus zu aktivieren, durch zwei Dateien (mit jeglichem Inhalt, normalerweise leer) ersetzt:
- $ PGDATA / recovery.signal - ideologischer Nachfolger standby_mode = off, die Wiederherstellung aus dem Archiv wird bis zu dem in den Konfigurationen angegebenen Punkt durchgeführt.
- $ PGDATA / standby.signal - bzw. standby_mode = on. Wir werden diese Datei auf allen Replikaten sehen.
Wenn der Startvorgang der Datenbank beide Dateien gefunden hat, gehen wir davon aus, dass wir uns im Standby-Modus befinden.
Wenn aus Gründen der Übersichtlichkeit die Parameteränderungen an einer Platte reduziert werden sollen:
alte recovery.conf
| PostgreSQL 12+ postgresql.conf
|
---|
primary_conninfo
| primary_conninfo
|
Primärslotname
| Primärslotname
|
trigger_file
| fördern_trigger_file
|
recovery_min_apply_delay
| recovery_min_apply_delay
|
Wiederherstellungsziel
| Wiederherstellungsziel
|
Wiederherstellungszielname
| Wiederherstellungszielname
|
recovery_target_time
| recovery_target_time
|
recovery_target_xid
| recovery_target_xid
|
recovery_target_lsn
| recovery_target_lsn
|
recovery_target_inclusive
| recovery_target_inclusive
|
recovery_target_timeline
| recovery_target_timeline
|
recovery_target_action
| recovery_target_action
|
Wiederherstellungsbefehl
| Wiederherstellungsbefehl
|
archive_cleanup_command
| archive_cleanup_command
|
recovery_end_command
| recovery_end_command
|
Sie können sehen, dass etwas weniger als nichts geändert wurde. Im Moment (mit Ausnahme des Präfixes "promotion_ "für" Promotion_Trigger_Datei ") werden alle neuen Parameter wie die alten benannt und nehmen die gleichen möglichen Werte an. Obwohl sich die Einstellungen des Wiederherstellungsziels noch ändern. Ich weiß nicht, ob dies zuvor von jemandem verwendet wurde, aber es war ein dokumentiertes Verhalten und es war möglich, mehrere Wiederherstellungsziele, Wiederherstellungsziele_lsn, Wiederherstellungszielnamen, Wiederherstellungszielzeiten oder Wiederherstellungsziele_xid gleichzeitig anzugeben. Zum Beispiel
recovery_target_lsn = '1/1D9FEA00' recovery_target_xid = '5238954'
Die letzte Zeile von recovery.conf wurde tatsächlich für die Wiederherstellung verwendet. Dies ist nicht mehr möglich, das Ziel für die Wiederherstellung sollte durch maximal eins angegeben werden. Aufgrund der Logik der GUC-Infrastruktur können Sie den gleichnamigen Parameter jedoch mehrmals angeben:
recovery_target_lsn = '1/1D9FEA00' recovery_target_lsn = '1/16AC7D0'
Dies ist akzeptabel. Wir werden auf den zuletzt angegebenen Einstellungswert zurückgesetzt.
Und im Allgemeinen ist dies alles, was über die Änderungen gesagt werden muss, die von außerhalb von PostgreSQL sichtbar sind. pg_basebackup -R (--write-recovery-conf) blieb an seinem Platz und macht das, was beabsichtigt ist. Erst jetzt werden Parameter zu postgresql.auto.conf anstelle von recovery.conf hinzugefügt und eine standby.signal-Datei erstellt
Wenn ich sage, dass dies alle Änderungen sind, die derzeit sichtbar sind, meine ich das leider genau. Alle neuen Parameter sind weiterhin als PGC_POSTMASTER festgelegt, dh sie können nur beim Start von PostgreSQL geändert werden. Wie bereits erwähnt, war dies eine Anforderung der Entwicklergemeinde: Übertragen Sie zunächst alle Einstellungen und prüfen Sie erst dann, ob sie in der laufenden Datenbank geändert werden können. Jetzt befindet sich PostgreSQL in einem wunderbaren Entwicklungsstadium, in dem das alte Verhalten bereits gebrochen wurde und Änderungen zum Besseren noch nicht vorgenommen wurden.
Ich habe bereits
einen Patch veröffentlicht , mit dem sich primary_conninfo und primary_slot_name im laufenden Betrieb ändern lassen. Mal sehen, was passiert.
Entschuldigung, ich habe Ihre recovery.conf gebrochen
UPD 7. April 2019
Am letzten Tag vor Feature Freeze Version 12 können Sie zusammenfassen. Das Ändern der Replikationseinstellungen war in der Version nicht enthalten. Dies ist natürlich auch eine merkwürdige Geschichte. Es war einmal, dass der von mir als Grundlage genommene Simon Riggs-Patch bereits Änderungen für den Neustart des Walreceivers beim Ändern der Verbindungseinstellungen enthielt. Ich habe sie in einem separaten Patch ausgewählt, der durch Dokumentation und Tests ergänzt wird. Und nach 6 Patch-Updates und ein paar Monaten Diskussion wird die offensichtliche Tatsache angezeigt, dass die Datenbank beim Neustart von walreceiver versucht, die Dateien von restore_command wiederherzustellen. Ein recht einfaches Verhalten der Zustandsmaschine, das durch das Herunterfahren des Walreceivers aus irgendeinem Grund ausgelöst wird. Dies stellt sich jedoch als "etwas heraus, das wir nicht wollen". Nun, früher war es unmöglich zu sagen? Ok, ich habe es irgendwie überarbeitet, aber der Kalender hatte bereits das endgültige Commitfest für Version 12 und niemand hat hier gesucht. Im Allgemeinen ist dies keine schnelle Sache, Patches in PostgreSQL tun dies. Aber ich habe das Recht, mich in die Liste der Personen aufzunehmen, dank
derer der epischste unvollendete unvollendete REINDEX CONCURRENTLY in Version 12 enthalten war!
Es ist am Ende erwähnenswert, dass eine Reihe von Einstellungen
die Möglichkeit haben , sich im laufenden Betrieb zu ändern: archive_cleanup_command, boost_trigger_file, recovery_end_command, recovery_min_apply_delay