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

Upgrade auf PostgreSQL 11 mit logischer Replikation

Es ist soweit.

Vor etwa einem Jahr haben wir PostgreSQL 10 mit Unterstützung für native logische Replikation veröffentlicht. Eine der Anwendungen der logischen Replikation besteht darin, Upgrades zwischen PostgreSQL-Hauptversionen mit geringer oder keiner Ausfallzeit zu ermöglichen. Bisher war PostgreSQL 10 die einzige PostgreSQL-Version mit nativer logischer Replikation, daher gab es nicht viele Möglichkeiten für ein Upgrade auf diese Weise. (Die logische Replikation kann auch zum Verschieben von Daten zwischen Instanzen auf verschiedenen Betriebssystemen oder CPU-Architekturen oder mit unterschiedlichen Low-Level-Konfigurationseinstellungen wie Blockgröße oder Gebietsschema verwendet werden – Sidegrading, wenn Sie so wollen.) Jetzt, da PostgreSQL 11 in der Nähe ist, wird es so sein weitere Gründe, diese Funktionalität zu nutzen.

Vergleichen wir zunächst die drei wichtigsten Möglichkeiten zum Upgrade einer PostgreSQL-Installation:

  • pg_dump und wiederherstellen
  • pg_upgrade
  • logische Replikation

Wir können diese Methoden in Bezug auf Robustheit, Geschwindigkeit, erforderliche Ausfallzeiten und Einschränkungen (und mehr, aber wir müssen irgendwo für diesen Artikel aufhören).

pg_dump and restore ist wohl die robusteste Methode, da sie die am besten getestete ist und seit Jahrzehnten verwendet wird. Es hat auch sehr wenige Einschränkungen in Bezug auf das, was es handhaben kann. Es ist möglich, Datenbanken zu erstellen, die nicht gesichert und wiederhergestellt werden können, meistens mit bestimmten Objektabhängigkeitsbeziehungen, aber diese sind selten und beinhalten normalerweise abgeratene Praktiken.

Das Problem bei der Dump- und Restore-Methode besteht natürlich darin, dass sie während der gesamten Zeit, in der die Dump- und Restore-Operationen ausgeführt werden, tatsächlich eine Ausfallzeit erfordert. Während die Quelldatenbank noch lesbar und beschreibbar ist, während der Prozess ausgeführt wird, gehen alle Aktualisierungen der Quelldatenbank nach dem Start des Speicherauszugs verloren.

pg_upgrade verbessert den pg_dump-Prozess, indem es die Datendateien direkt verschiebt, ohne sie in eine logische Textform ausgeben zu müssen. Beachten Sie, dass pg_upgrade intern immer noch pg_dump verwendet, um das Schema zu kopieren, aber nicht die Daten. Als pg_upgrade neu war, wurde seine Robustheit in Frage gestellt und einige Datenbanken wurden falsch aktualisiert. Aber pg_upgrade ist inzwischen ziemlich ausgereift und gut getestet, sodass man nicht mehr zögern muss, es aus diesem Grund zu verwenden. Während pg_upgrade läuft, ist das Datenbanksystem heruntergefahren. Aber man kann wählen, wie lange pg_upgrade läuft. Im Standard-Kopiermodus setzt sich die Gesamtlaufzeit zusammen aus der Zeit zum Sichern und Wiederherstellen des Schemas (was normalerweise sehr schnell geht, es sei denn, man hat Tausende von Tabellen oder anderen Objekten) plus der Zeit zum Kopieren der Datendateien, die davon abhängt wie groß die Datenbank ist (und das I/O-System, Dateisystem etc.).

Im optionalen Link-Modus werden die Datendateien stattdessen fest mit dem neuen Datenverzeichnis verknüpft, sodass die Zeit lediglich die Zeit ist, eine kurze Kernel-Operation pro Datei durchzuführen, anstatt jedes Byte zu kopieren. Der Nachteil ist, dass, wenn beim Upgrade etwas schief geht oder Sie auf die alte Installation zurückgreifen müssen, dieser Vorgang Ihre alte Datenbank zerstört hat. (Ich arbeite an einer Lösung, die das Beste aus beiden Welten für PostgreSQL 12 bietet und Reflinks oder Dateiklonoperationen auf unterstützten Dateisystemen verwendet.)

Die logische Replikation ist hier das Neueste im Bunde, daher wird es wahrscheinlich einige Zeit dauern, die Knicke zu lösen. Wenn Sie keine Zeit zum Erkunden und Nachforschen haben, ist dies im Moment möglicherweise nicht der richtige Weg. (Natürlich verwenden die Leute seit vielen Jahren andere logische Replikationslösungen, die nicht zum Kerngeschäft gehören, wie Slony, Londiste und pglogical, um PostgreSQL zu aktualisieren, daher gibt es viel Erfahrung mit den Prinzipien, wenn nicht mit den Einzelheiten.)

Der Vorteil der Verwendung der logischen Replikation für das Upgrade besteht darin, dass die Anwendung weiterhin für die alte Instanz ausgeführt werden kann, während die Datensynchronisierung stattfindet. Es muss nur ein kleiner Ausfall auftreten, während die Client-Verbindungen umgeschaltet werden. Während also ein Upgrade mit logischer Replikation wahrscheinlich von Anfang bis Ende langsamer ist als die Verwendung von pg_upgrade im Kopiermodus (und definitiv langsamer als die Verwendung des Hardlink-Modus), spielt es keine große Rolle, da die tatsächliche Ausfallzeit viel kürzer sein kann.

Beachten Sie, dass die logische Replikation derzeit keine Schemaänderungen repliziert. Bei diesem vorgeschlagenen Upgrade-Verfahren wird das Schema weiterhin über pg_dump kopiert, spätere Schemaänderungen werden jedoch nicht übernommen. Das Upgrade mit logischer Replikation hat auch einige andere Einschränkungen. Bestimmte Vorgänge werden nicht von der logischen Replikation erfasst:große Objekte, TRUNCATE, Sequenzänderungen. Wir werden Problemumgehungen für diese Probleme später diskutieren.

Wenn Sie physische Reserven haben (und wenn nicht, warum nicht?), gibt es auch einige Unterschiede zwischen den Methoden zu beachten. Bei beiden Methoden müssen Sie neue physische Standbys für die aktualisierte Instanz erstellen. Mit Dump und Restore sowie mit logischer Replikation können sie eingerichtet werden, bevor das Upgrade beginnt, sodass die Standby-Instanz größtenteils bereit ist, sobald die Wiederherstellung oder die anfängliche Synchronisierung der logischen Replikation abgeschlossen ist, vorbehaltlich einer Replikationsverzögerung.

Mit pg_upgrade müssen die neuen Standbys erstellt werden, nachdem das Upgrade des primären abgeschlossen ist. (Die pg_upgrade-Dokumentation beschreibt dies ausführlicher.) Wenn Sie sich für Hochverfügbarkeit auf physische Standbys verlassen, sollten die Standbys vorhanden sein, bevor Sie auf die neue Instanz umschalten, sodass die Einrichtung der Standbys Ihre gesamten Timing-Berechnungen beeinflussen könnte.

Aber zurück zur logischen Replikation. So kann ein Upgrade mit logischer Replikation durchgeführt werden:

0. Die alte Instanz muss für die logische Replikation vorbereitet werden. Dies erfordert einige Konfigurationseinstellungen, wie unter http://www.postgresql.org/docs/10/static/logical-replication-config.html beschrieben (hauptsächlich wal_level = logical . Wenn sich herausstellt, dass Sie diese Änderungen vornehmen müssen, erfordern sie einen Neustart des Servers. Überprüfen Sie dies also rechtzeitig. Überprüfen Sie auch die pg_hba.conf auf der alten Instanz so eingerichtet ist, dass Verbindungen von der neuen Instanz akzeptiert werden. (Um das zu ändern, muss nur neu geladen werden.)

1. Installieren Sie die neue PostgreSQL-Version. Sie benötigen mindestens das Serverpaket und das Clientpaket, das pg_dump enthält. Viele Pakete erlauben jetzt die Installation mehrerer Versionen nebeneinander. Wenn Sie virtuelle Maschinen oder Cloud-Instanzen ausführen, sollten Sie erwägen, die neue Instanz auf einem neuen Host zu installieren.

2. Richten Sie eine neue Instanz ein, dh führen Sie initdb aus. Die neue Instanz kann andere Einstellungen als die alte haben, z. B. Gebietsschema, WAL-Segmentgröße oder Prüfsummenbildung. (Warum nutzen Sie diese Gelegenheit nicht, um Datenprüfsummen einzuschalten?)

3. Bevor Sie die neue Instanz starten, müssen Sie möglicherweise einige Konfigurationseinstellungen ändern. Wenn die Instanz auf demselben Host wie die alte Instanz ausgeführt wird, müssen Sie eine andere Portnummer festlegen. Übernehmen Sie auch alle benutzerdefinierten Änderungen, die Sie in postgresql.conf vorgenommen haben auf Ihrer alten Instanz, wie Speichereinstellungen, max_connections usw. Erstellen Sie auf ähnliche Weise pg_hba.conf Einstellungen, die Ihrer Umgebung entsprechen. Sie können normalerweise beginnen, indem Sie die pg_hba.conf kopieren Datei aus der alten Instanz. Wenn Sie SSL verwenden möchten, richten Sie dies jetzt ein.

4. Starten Sie die neue (leere) Instanz und prüfen Sie, ob sie zu Ihrer Zufriedenheit funktioniert. Wenn Sie die neue Instanz auf einem neuen Host einrichten, überprüfen Sie an dieser Stelle, ob Sie eine Datenbankverbindung (über psql) vom neuen Host zur alten Datenbankinstanz herstellen können. Wir werden dies in den folgenden Schritten benötigen.

5. Kopieren Sie die Schemadefinitionen mit pg_dumpall. (Oder Sie können es mit pg_dump für jede Datenbank separat machen, aber dann vergessen Sie nicht globale Objekte wie Rollen.)

pg_dumpall -s >schemadump.sql
psql -d postgres -f schemadump.sql

Alle Schemaänderungen nach diesem Zeitpunkt werden nicht migriert. Diese müssten Sie selbst verwalten. In vielen Fällen können Sie die sich ändernde DDL einfach auf beide Hosts anwenden, aber das Ausführen von Befehlen, die die Tabellenstruktur während eines Upgrades ändern, ist wahrscheinlich eine zu große Herausforderung.

6. Erstellen Sie in jeder Datenbank in der Quellinstanz eine Veröffentlichung, die alle Tabellen erfasst:

CREATE PUBLICATION p_upgrade FOR ALL TABLES;

Die logische Replikation funktioniert in jeder Datenbank separat, daher muss dies in jeder Datenbank wiederholt werden. Andererseits müssen Sie nicht alle Datenbanken auf einmal aktualisieren, also können Sie diese eine Datenbank nach der anderen tun oder sogar einige Datenbanken nicht aktualisieren.

7. Erstellen Sie in jeder Datenbank in der Zielinstanz ein Abonnement, das die gerade erstellte Veröffentlichung abonniert. Achten Sie darauf, die Quell- und Zieldatenbanken korrekt abzugleichen.

CREATE SUBSCRIPTION s_upgrade CONNECTION 'host=oldhost port=oldport dbname=dbname ...' PUBLICATION p_upgrade;

Stellen Sie die Verbindungsparameter entsprechend ein.

8. Nun warten Sie, bis die Abonnements die Ausgangsdaten übernommen haben und den Publisher vollständig eingeholt haben. Sie können den anfänglichen Synchronisierungsstatus jeder Tabelle in einem Abonnement im Systemkatalog pg_subscription_rel überprüfen (Suchen Sie nach r =fertig in Spalte srsubstate ). Der Gesamtstatus der Replikation kann in pg_stat_replication überprüft werden auf der Senderseite und pg_stat_subscription auf der Empfängerseite.

9. Wie oben erwähnt, werden Sequenzänderungen nicht repliziert. Eine mögliche Problemumgehung besteht darin, die Sequenzwerte mit pg_dump zu kopieren. Sie können einen Dump der aktuellen Sequenzwerte wie folgt erhalten:

pg_dump -d dbname --data-only -t '*_seq' >seq-data.sql

(Dies setzt voraus, dass die Sequenznamen alle mit *_seq übereinstimmen und keine Tabelle entspricht diesem Namen. In komplizierteren Fällen können Sie auch einen vollständigen Dump erstellen und die Sequenzdaten aus dem Inhaltsverzeichnis des Dumps extrahieren.)

Da die Sequenzen dabei möglicherweise fortschreiten, mungieren Sie vielleicht die seq-data.sql Datei, um den Zahlen etwas mehr Spielraum zu geben.

Stellen Sie diese Datei dann mit psql in der neuen Datenbank wieder her.

10. Showtime:Stellen Sie die Anwendungen auf die neuen Instanzen um. Dies erfordert einige Überlegungen im Voraus. Im einfachsten Fall stoppen Sie Ihre Anwendungsprogramme, ändern die Verbindungseinstellungen, starten neu. Wenn Sie einen Verbindungsproxy verwenden, können Sie die Verbindung dort umstellen. Sie können die Client-Anwendungen auch einzeln wechseln, vielleicht um die Dinge ein wenig auszuprobieren oder das neue System zu entlasten. Dies funktioniert, solange die Anwendungen, die noch auf den alten Server zeigen, und diejenigen, die auf den neuen Server zeigen, keine widersprüchlichen Schreibvorgänge durchführen. (In diesem Fall würden Sie zumindest für kurze Zeit ein Multimaster-System betreiben, und das ist eine andere Größenordnung der Komplexität.)

11. Wenn das Upgrade abgeschlossen ist, können Sie das Replikations-Setup herunterfahren. Führen Sie in jeder Datenbank auf der neuen Instanz

aus
DROP SUBSCRIPTION s_upgrade;

Wenn Sie die alte Instanz bereits heruntergefahren haben, schlägt dies fehl, da sie den Remote-Server nicht erreichen kann, um den Replikationsslot zu löschen. Siehe die Manpage DROP SUBSCRIPTION für die Vorgehensweise in dieser Situation.

Sie können die Veröffentlichungen auch auf der Quellinstanz ablegen, dies ist jedoch nicht erforderlich, da eine Veröffentlichung keine Ressourcen behält.

12. Entfernen Sie schließlich die alten Instanzen, wenn Sie sie nicht mehr benötigen.

Einige zusätzliche Kommentare zu Problemumgehungen für Dinge, die von der logischen Replikation nicht unterstützt werden. Wenn Sie große Objekte verwenden, können Sie diese mit pg_dump verschieben, sofern sie sich während des Upgrade-Prozesses nicht ändern. Dies ist eine erhebliche Einschränkung. Wenn Sie also häufig große Objekte verwenden, ist diese Methode möglicherweise nicht für Sie geeignet. Wenn Ihre Anwendung während des Upgrade-Vorgangs TRUNCATE ausgibt, werden diese Aktionen nicht repliziert. Vielleicht können Sie Ihre Anwendung optimieren, um dies für die Zeit des Upgrades zu verhindern, oder Sie können stattdessen ein DELETE verwenden. PostgreSQL 11 unterstützt die Replikation von TRUNCATE, aber das funktioniert nur, wenn sowohl die Quell- als auch die Zielinstanz PostgreSQL 11 oder neuer sind.

Einige Schlussbemerkungen, die wirklich für alle Upgrade-Vorhaben gelten:

  • Anwendungen und alle Datenbank-Client-Programme sollten mit einer neuen Hauptversion von PostgreSQL getestet werden, bevor sie in Produktion gehen.
  • Zu diesem Zweck sollten Sie auch das Upgrade-Verfahren testen, bevor Sie es in der Produktionsumgebung ausführen.
  • Schreiben Sie Dinge auf oder besser Skripte und automatisieren Sie so viel wie möglich.
  • Stellen Sie sicher, dass Ihre Sicherungseinrichtung, Überwachungssysteme und alle Wartungstools und -skripte während des Upgrade-Vorgangs entsprechend angepasst werden. Idealerweise sollten diese vorhanden sein und überprüft werden, bevor die Umstellung erfolgt.

In diesem Sinne viel Glück und bitte teilen Sie Ihre Erfahrungen.