Nahtlose (fast) Migration zwischen wichtigen PostgreSQL-Versionen mithilfe der logischen Replikation

In True Engineering musste bei einem Projekt die Version von PostgreSQL von 9.6 auf 11.1 geändert werden.

Warum? Die Datenbank des Projekts ist bereits 1,5 TB groß und wächst. Die Leistung ist eine der Hauptanforderungen an das System. Und die Datenstruktur selbst entwickelt sich weiter: Neue Spalten werden hinzugefügt, vorhandene geändert. Die neue Version von Postgres hat gelernt, wie man effizient arbeitet, indem neue Spalten mit einem Standardwert hinzugefügt werden, sodass keine benutzerdefinierten Krücken auf Anwendungsebene eingezäunt werden müssen. Selbst in der neuen Version wurden mehrere neue Möglichkeiten zum Partitionieren von Tabellen hinzugefügt, was auch unter Bedingungen einer großen Datenmenge äußerst nützlich ist.

Es wird also entschieden, dass wir migrieren. Natürlich können Sie eine neue Version des PostgreSQL-Servers parallel zur alten Version erstellen, die Anwendung stoppen, die Datenbank mit dump / restore (oder pg_upgrade) verschieben und die Anwendung neu starten. Diese Lösung passte aufgrund der Größe der Basis nicht zu uns. Außerdem arbeitet die Anwendung im Kampfmodus und es gibt nur wenige Minuten bis zur Ausfallzeit.

Aus diesem Grund haben wir uns entschlossen, die Migration mithilfe der logischen Replikation in PostgreSQL mithilfe eines Plugins eines Drittanbieters namens pglogical zu versuchen .

Während des "Prozess" -Prozesses stießen wir auf eine sehr fragmentarische Dokumentation dieses Prozesses (und auf Russisch überhaupt nicht) sowie auf einige Fallstricke und nicht offensichtliche Nuancen. In diesem Artikel möchten wir unsere Erfahrungen in Form eines Tutorials präsentieren.



TL; DR

  • Alles stellte sich heraus (nicht ohne Krücken, ein Artikel darüber).
  • Sie können innerhalb der PostgreSQL-Version von 9.4 auf 11.x von jeder Version auf eine beliebige Version nach unten oder oben migrieren.
  • Die Ausfallzeit entspricht der Zeit, die Ihre Anwendung benötigt, um die Verbindung zum neuen Datenbankserver wiederherzustellen (in unserem Fall war dies ein Neustart der gesamten Anwendung, in der Wildnis jedoch offensichtlich „mögliche Optionen“).

Warum passte die "Stirn" -Lösung nicht zu uns?


Wie bereits erwähnt, besteht der einfachste Ausweg darin, die neue Version des PostgreSQL-Servers parallel zur alten Version zu erstellen, die Anwendung zu stoppen, die Datenbank mit dump / restore (oder pg_upgrade) zu verschieben und die Anwendung erneut zu starten. Für Datenbanken mit kleinem Volumen ist dies im Prinzip eine durchaus geeignete Option (oder im Allgemeinen ist das Volumen unwichtig, wenn Sie die Möglichkeit haben, die Anwendung für den Zeitraum der "Transfusion" der Datenbank vom alten auf den neuen Server zu verlängern, unabhängig davon, wie lange diese Zeit dauert). In unserem Fall benötigt die Datenbank jedoch etwa 1,5 TB auf der Festplatte, und das Verschieben ist keine Frage von Minuten, sondern von mehreren Stunden. Die Anwendung arbeitet wiederum im Kampfmodus, und ich wollte Ausfallzeiten unbedingt länger als ein paar Minuten vermeiden.

Gegen diese Option war auch die Tatsache, dass wir die Master-Slave-Replikation verwenden und den Slave-Server nicht sicher aus dem Workflow ausschalten können. Um die Anwendung nach der Migration des Master-Servers von der alten Version von PostgreSQL auf die neue Version umzustellen, muss vor dem Starten der Anwendung ein neuer Slave-Server vorbereitet werden. Und dies sind noch einige Stunden Ausfallzeit, bis der Slave erstellt wird (obwohl viel weniger als die Migration des Masters).

Aus diesem Grund haben wir uns entschlossen, die Migration mithilfe der logischen Replikation in PostgreSQL mithilfe eines Plugins eines Drittanbieters namens pglogical zu versuchen.

allgemeine Informationen


pglogical ist ein logisches Replikationssystem, das die native logische Dekodierung in PostgreSQL verwendet und als PostgreSQL-Erweiterung implementiert ist. Ermöglicht die Konfiguration der selektiven Replikation mithilfe des Abonnement- / Veröffentlichungsmodells. Es ist nicht erforderlich, Trigger in der Datenbank zu erstellen oder externe Dienstprogramme für die Replikation zu verwenden.

Die Erweiterung funktioniert mit jeder Version von PostgreSQL ab 9.4 (seit Logical Decoding erstmals in 9.4 veröffentlicht wurde) und ermöglicht Ihnen die Migration zwischen unterstützten Versionen von PostgreSQL in jede Richtung.

Das manuelle Einrichten der Replikation mithilfe von pglogical manuell ist nicht sehr trivial, obwohl dies im Prinzip durchaus möglich ist. Glücklicherweise gibt es ein Drittanbieter-Dienstprogramm pgrepup zur Automatisierung des Konfigurationsprozesses, das wir verwenden werden.

Speicherplatz Memo


Da wir planen, die neue Version von PostgreSQL parallel zur alten Version auf denselben Servern zu aktualisieren, verdoppeln sich die Festplattenanforderungen für die Datenbank auf den Master- und Slave-Servern. Es scheint, dass dies offensichtlich ist, aber ... Achten Sie einfach auf genügend freien Speicherplatz, bevor Sie mit der Replikation beginnen, um die ziellos verbrachten Jahre nicht zu bereuen.

In unserem Fall waren Datenbankänderungen erforderlich, und das Speicherformat während der Migration zwischen 9.6 und 11 „schwillt“ nicht zugunsten der neuesten Version an, sodass der Speicherplatz nicht um 2, sondern um das 2,2-fache erhöht werden musste. Lob LVM, dies kann im Zuge der Migration im laufenden Betrieb erfolgen.

Im Allgemeinen kümmern Sie sich darum.

Installieren Sie PostgreSQL 11 auf dem Master


Hinweis: Wir verwenden Oracle Linux. Alle folgenden Elemente werden für diese Distribution geschärft. Es ist möglich, dass andere Linux-Distributionen eine kleine Überarbeitung einer Datei erfordern, aber es ist unwahrscheinlich, dass dies von Bedeutung ist.
#   yum install https://download.postgresql.org/pub/repos/yum/11/redhat/rhel-7-x86_64/pgdg-oraclelinux11-11-2.noarch.rpm #   postgresql11 yum install postgresql11 postgresql11-devel postgresql11-server postgresql11-contrib #   /usr/pgsql-11/bin/postgresql-11-setup initdb 

Das alte Datenverzeichnis befindet sich in /var/lib/pgsql/9.6/data , das neue in / var / lib / pgsql / 11 / data

Kopieren Sie die Zugriffseinstellungen ( pg_hba.conf ) und Servereinstellungen ( postgresql.conf ) von 9.6 auf 11.

Um zwei PostgreSQL-Server auf demselben Computer auszuführen , ändern Sie in der Konfigurationskonfiguration postgresql.conf 11 den Port in 15432 (port = 15432).

Hier müssen Sie sorgfältig überlegen, was Sie in der neuen Version von PostgreSQL in Ihrem Fall noch tun müssen, damit es mit Ihrer postgresql.conf beginnt (und Ihre Anwendung möglicherweise damit funktioniert). In unserem Fall mussten die von uns in der neuen Version verwendeten PostgreSQL-Erweiterungen installiert werden. Dies würde den Rahmen des Artikels sprengen. Lassen Sie das neue PostgreSQL einfach starten, funktionieren und ganz zu Ihnen passen :)

 #  ,  ,  shared libraries, whatever... # .... #  systemctl enable postgresql-11 systemctl start postgresql-11 

Wir schauen in / var / lib / pgsql / 11 / data / pg_log / . Alles ist gut? Wir machen weiter!

Installieren und konfigurieren Sie pgrepup


 #  python yum install python yum install python2-pip #  pgrepup pip install pgrepup #   pgrepup config 



Nuancen:

  1. Als app_owner geben wir den Benutzer an, unter dem die PostgreSQL-Server ausgeführt werden.
  2. Geben Sie für Datenbank template1 an .
  3. Benutzername und Passwort - Daten für den Superuser-Zugriff. In unserem Fall wurde die Vertrauensmethode in pg_hba.conf für lokale Verbindungen des Postgres- Benutzers angegeben, sodass Sie ein beliebiges Kennwort angeben können.

Konfigurieren Sie die Replikation


 #   pgrepup check 

Wir erhalten die Ausgabe einer Liste vieler Parameter, die nach Bedarf konfiguriert werden müssen.

Beispiel für Überprüfungsergebnisse:





Alle Fehler während der Überprüfung müssen beseitigt werden. In den Einstellungen beider Server sollten wal_level = LOGICAL (damit die logische Dekodierung funktioniert) festgelegt werden, die erforderlichen Einstellungen für die Replikations-Engine (Anzahl der Slots und wal_senders ). Die Hinweise des Dienstprogramms pgrepup sind recht informativ, Fragen sollten in den meisten Punkten nicht auftauchen.

Wir nehmen alle notwendigen Einstellungen vor, die pgrepup verlangt.

In beiden Dateien pg_hba.conf fügen wir an der Eingabeaufforderung pgrepup Berechtigungen für den Benutzer hinzu, der die Replikation durchführen soll:

 host replication pgrepup_replication 127.0.0.1/32 md5 host all pgrepup_replication 127.0.0.1/32 md5 

Primärschlüssel hinzufügen


Damit die Replikation funktioniert, muss in allen Tabellen ein Primärschlüssel definiert sein.

In unserem Fall war PK nicht überall, daher müssen Sie es zum Zeitpunkt der Replikation hinzufügen und am Ende der Replikation gegebenenfalls löschen.

Eine Liste von Tabellen ohne PK erzeugt unter anderem eine pgrepup check . Für alle Tabellen aus dieser Liste müssen Sie einen Primärschlüssel hinzufügen, der zu Ihnen passt. In unserem Fall war es so etwas wie:

 ALTER TABLE %s ADD COLUMN temporary_pk BIGSERIAL NOT NULL PRIMARY KEY 

Das Dienstprogramm pgrepup verfügt über einen integrierten Befehl zum Ausführen dieses Vorgangs ( pgrepup fix ). Wenn es verwendet wird, wird sogar impliziert, dass diese temporären Spalten bei erfolgreicher Replikation automatisch gelöscht werden. Leider war diese Funktionalität auf großen Basen so illusorisch und bezaubernd fehlerhaft, dass wir beschlossen, sie nicht zu verwenden, sondern diesen Vorgang manuell durchzuführen, da dies für uns praktisch ist.

Installieren Sie die pglogische Erweiterung


Anweisungen zur Installation der Erweiterung finden Sie hier . Die Erweiterung muss auf beiden Servern installiert sein.

 #       curl https://access.2ndquadrant.com/api/repository/dl/default/release/9.6/rpm | bash curl https://access.2ndquadrant.com/api/repository/dl/default/release/11/rpm | bash #   yum install postgresql96-pglogical postgresql11-pglogical 

Fügen Sie die Bibliothekslast in der postgresql.conf beider Server hinzu:

 shared_preload_libraries = 'pglogical' 

Installieren Sie die Erweiterung pgl_ddl_deploy


Dies ist eine Hilfserweiterung, die pgrepup für die logische DDL-Replikation verwendet.

 #      git clone https://github.com/enova/pgl_ddl_deploy.git #       PATH=/usr/pgsql-9.6/bin/:$PATH USE_PGXS=1 make USE_PGXS=1 make install make clean #       PATH=/usr/pgsql-11/bin/:$PATH make CLANG=true make install 

Fügen Sie die Bibliothekslast in der postgresql.conf beider Server hinzu:

 shared_preload_libraries = 'pglogical,pgl_ddl_deploy' 

Änderungen überprüfen


 #   postgresql systemctl restart postgresql-11 

Jetzt pgrepup check Sie mit pgrepup check sicherstellen, dass mit dem Zielserver alles in Ordnung ist und alle Kommentare zum Zielserver vollständig entfernt wurden.

Wenn alles in Ordnung ist, können Sie den alten Server neu starten. Hier müssen Sie überlegen, wie Ihre Anwendung auf den Neustart des Datenbankservers reagiert. Vielleicht sollten Sie ihn zuerst stoppen.

 #  systemctl restart postgresql-9.6 #  pgrepup check 

In der Ausgabe des Befehls sollten nun alle Elemente als OK markiert werden.

Es scheint, dass Sie mit der Migration beginnen können, aber ...

Beheben Sie pgrepup-Fehler


In der aktuellen Version von pgrepup gibt es mehrere Fehler, die eine Migration unmöglich machen. Pull-Anforderungen wurden gesendet, aber leider werden sie ignoriert, sodass Sie Korrekturen manuell vornehmen müssen.

Wir gehen zum Installationsordner von pgrepup (unser Fall ist /usr/lib/python2.7/site-packages/pgrepup/commands/ ).

Mach es einmal. **kwargs in jeder * .py- Datei die fehlenden **kwargs in die Funktionsbeschreibung ein. Ein Bild ist besser als tausend Worte:



Hier verpflichten .

Mach zwei. In setup.py suchen wir nach "sh -c", zwei Einträgen, alle mehrzeiligen Shell-Befehle müssen einzeilig sein.

Hier verpflichten .

Starten Sie die Migration


 #  pgrepup setup 

Mit diesem Befehl bereitet pgrepup beide Server auf den Start der Replikation vor, erstellt einen Benutzer, konfiguriert pglogical und überträgt das Datenbankschema.



 #   pgrepup start 

Er sagte: "Lass uns gehen!" und winkte mit der Hand:



Die Replikation wird ausgeführt. Die aktuelle Situation kann mit dem Befehl pgrepup status :



Hier sehen wir, dass zwei Datenbanken bereits verschoben wurden und die Replikation ausgeführt wird und eine noch verschoben wird. Jetzt müssen Sie nur noch Kaffee trinken und warten, bis das gesamte Volumen der ursprünglichen Datenbank gepumpt ist.

Unterwegs können Sie tiefer in die Pgrepup-Fassade schauen und sehen, was unter der Haube passiert. Hier ist eine Liste von Fragen als Ausgangspunkt für anfragende Köpfe:

 SELECT * FROM pg_replication_origin_status ORDER BY remote_lsn DESC; SELECT *,pg_xlog_location_diff(s.sent_location,s.replay_location) byte_lag FROM pg_stat_replication s; SELECT query FROM pg_stat_activity WHERE application_name='subscription_copy' 

Wenn wir viel Kaffee trinken (auf dem Testserver beim Schreiben dieses Artikels dauerte die Migration von ~ 700 GB Daten ungefähr einen Tag), sehen wir endlich das folgende Bild:



Und das heißt, es ist Zeit, einen neuen Sklaven vorzubereiten.

Installieren Sie PostgreSQL 11 auf Slave


Hier ist alles einfach und laut Lehrbuch keine Nuancen.

 #   yum install https://download.postgresql.org/pub/repos/yum/11/redhat/rhel-7-x86_64/pgdg-oraclelinux11-11-2.noarch.rpm #  postgresql 11 yum install postgresql11 postgresql11-devel postgresql11-server postgresql11-contrib #      su - postgres pg_basebackup -h db-master.hostname -p 15432 -D /var/lib/pgsql/11/data/ -R -P -U replication -X stream -c fast 

Kopieren Sie die Zugriffseinstellungen ( pg_hba.conf ) und Servereinstellungen ( postgresql.conf ) von 9.6 auf 11. Ändern Sie in der Konfigurationskonfiguration postgresql.conf 11 den Port in 15432 (port = 15432).

 #  systemctl enable postgresql-11 systemctl start postgresql-11 

 #     Master SELECT *,pg_wal_lsn_diff(s.sent_lsn,s.replay_lsn) AS byte_lag FROM pg_stat_replication s; #     Slave SELECT now()-pg_last_xact_replay_timestamp(); 

Zwischensummen


Nach all diesen Prozeduren erhalten wir dieses knifflige Replikationsschema:



Als letzte Überprüfung (und am Ende ist es einfach wunderschön) können Sie hier ein UPDATE in der 9.6-Master-Datenbank durchführen und beobachten, wie es auf die anderen drei Server repliziert wird.

Bild

Umstellung der Anwendung auf die neue Version von PostgreSQL


Bisher hat unsere Anwendung nichts von der neuen Version von PostgreSQL vermutet. Es ist an der Zeit, dies zu beheben. Die Optionen hier hängen grundsätzlich nur von zwei Dingen ab:
Werden Sie die neuen Dienste an denselben Ports überwiegen, an denen die alten gearbeitet haben?
und ob Ihre Anwendung beim Neustart des Datenbankservers einen Neustart erfordert.

Zum Spaß werden wir beide Fragen mit „Ja“ beantworten und fortfahren.

Wir stoppen die Anwendung.

 # ,   , : SELECT * FROM pg_stat_activity; 

 #    #       sequences. pgrepup stop 



 #      pgrepup uninstall 



 #  master: #    systemctl disable postgresql-9.6 #   ,  ,  . systemctl stop postgresql-9.6 systemctl stop postgresql-11 #  slave: #    systemctl disable postgresql-9.6 #   ,  ,  . systemctl stop postgresql-9.6 systemctl stop postgresql-11 

Wir geben den Standardport in der postgresql.conf- Konfiguration der neuen Version an Master und Slave zurück.

Auf dem neuen Slave ändern wir auch den Port auf den Standardport in recovery.conf .

Auf dem Weg gibt es einen Vorschlag von sin, den Port für die inaktive alte Version weiter zu ändern:
Wir stellen den nicht standardmäßigen Port in der postgresql.conf der alten Version Master und Slave zur Verfügung.
Auf dem alten Slave ändern wir auch den Port in der Datei recovery.conf in einen nicht standardmäßigen.

 #   master systemctl enable postgresql-11 systemctl start postgresql-11 #   slave: systemctl enable postgresql-11 systemctl start postgresql-11 

Überprüfen Sie die Protokolle.

Überprüfen Sie den Replikationsstatus auf dem Master.

 SELECT *,pg_wal_lsn_diff(s.sent_lsn,s.replay_lsn) AS byte_lag FROM pg_stat_replication s; 

Wir starten die Anwendung. Wir freuen uns für eine halbe Stunde.

Und schließlich nützliche Literatur zum Thema:


Viel Glück!

Source: https://habr.com/ru/post/de437318/


All Articles