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

Switchover/Switchback in Slony-I während des Upgrades der PostgreSQL-Hauptversionen 8.4.x/9.3.x

Jede neue Version von PostgreSQL enthält eine Fülle aufregender Funktionen. Um neue Funktionen nutzen zu können, sollte der Datenbankserver aktualisiert werden. Die Auswahl herkömmlicher Upgrade-Pfade wie pg_dump/pg_restore oder pg_upgrade erfordert eine erhebliche Ausfallzeit der Anwendung. Wenn Sie heute nach einem Upgrade-Pfad mit minimaler Ausfallzeit zwischen den wichtigsten PostgreSQL-Versionen mit perfektem Rollback-Plan suchen, dann wird dies durch asynchrone Slony-I-Replikation erreicht. Da Slony-I (hier erfahren Sie mehr darüber) in der Lage ist, problemlos zwischen verschiedenen PostgreSQL-Versionen, Betriebssystemen und Bitarchitekturen zu replizieren, sind Upgrades ohne erhebliche Ausfallzeiten möglich. Darüber hinaus verfügt es über eine konsequente Switchover- und Switchback-Funktionalität im Design.

Meiner Meinung nach sollte es bei der Durchführung von Hauptversions-Upgrades einen geeigneten Fallback-Plan geben, denn nur für den Fall, dass sich die Anwendung als fehlerhaft herausstellt oder auf der aktualisierten Version nicht gut funktioniert, sollten wir in der Lage sein, sofort auf die ältere Version zurückzusetzen. Slony-I bietet eine solche Funktionalität in Form von Switchback. Dieser Beitrag demonstriert ein Upgrade mit minimaler Ausfallzeit, einschließlich Switchover/Switchback-Schritten.

Bevor Sie zur Demo gehen, ist ein wichtiger Schritt zu beachten, früher als PG 9.0.x Version Bytea-Datentyp-Spalten verwenden, um Daten im ESCAPE-Format und spätere Versionen im HEX-Format zu speichern. Während der Umschaltung (neuere Version auf ältere Version) wird diese Art von Bytea-Formatunterschieden von Slony-I nicht unterstützt, daher sollte das ESCAPE-Format während der gesamten Upgrade-Dauer beibehalten werden, andernfalls kann ein Fehler auftreten:

ERROR  remoteWorkerThread_1_1: error at end of COPY IN: ERROR:  invalid input syntax for type bytea
CONTEXT: COPY sl_log_1, line 1: "1 991380 1 100001 public foo I 0 {id,500003,name,"A ",b,"\\x41"}"
ERROR remoteWorkerThread_1: SYNC aborted

Zur Behebung sind auf PG 8.4.x keine Änderungen erforderlich, aber auf PG 9.3.5 sollte der bytea_output-Parameter wie gezeigt von HEX auf ESCAPE gesetzt werden. Wir können es auf Clusterebene ($PGDATA/postgresql.conf) oder Benutzerebene (ALTER TABLE…SET) festlegen, ich habe es vorgezogen, mit Änderungen auf Benutzerebene zu gehen.

slavedb=# alter user postgres set bytea_output to escape;
ALTER ROLE

Fahren wir mit den Upgrade-Schritten fort. Unten sind die Serverdetails meiner beiden Versionen, die in dieser Demo verwendet werden, ändern Sie sie entsprechend Ihrer Serverkonfiguration, wenn Sie es versuchen:

Origin Node (Master/Primary are called as Origin)                     Subscriber Node (Slave/Secondary are called as Subscriber)
------------------------------------------------- ----------------------------------------------------------
Host IP : 192.168.22.130 192.168.22.131
OS Version : RHEL 6.5 64 bit RHEL 6.5 64 bit
PG Version : 8.4.22 (5432 Port) 9.3.5 (5432 Port)
Slony Vers. : 2.2.2 2.2.2
PG Binaries : /usr/local/pg84/bin /opt/PostgreSQL/9.3/
Database : masterdb slavedb
PK Table : foo(id int primary key, name char(20), image bytea) ...restore PK tables structure from Origin...

Für ein einfaches Verständnis und eine einfache Implementierung habe ich die Demo in drei Abschnitte unterteilt

1. Kompilieren für Slony-I-Binärdateien gegen PostgreSQL-Versionen
2. Replikationsskripte erstellen und ausführen
3. Umschaltung/Rückschaltung testen.

1. Kompilieren für Slony-I-Binärdateien gegen die PostgreSQL-Version
Laden Sie Slony-I-Quellen von hier herunter und führen Sie eine Quelleninstallation für PostgreSQL-Binärdateien auf Ursprungs- und Abonnentenknoten durch.

On Origin Node:
# tar -xvf slony1-2.2.2.tar.bz2
# cd slony1-2.2.2
./configure --with-pgbindir=/usr/local/pg84/bin
--with-pglibdir=/usr/local/pg84/lib
--with-pgincludedir=/usr/local/pg84/include
--with-pgpkglibdir=/usr/local/pg84/lib/postgresql
--with-pgincludeserverdir=/usr/local/pg84/include/postgresql/
make
make install

On Subscriber Node: (assuming PG 9.3.5 installed)
# tar -xvf slony1-2.2.2.tar.bz2
# cd slony1-2.2.2
./configure --with-pgconfigdir=/opt/PostgreSQL/9.3/bin
--with-pgbindir=/opt/PostgreSQL/9.3/bin
--with-pglibdir=/opt/PostgreSQL/9.3/lib
--with-pgincludedir=/opt/PostgreSQL/9.3/include
--with-pgpkglibdir=/opt/PostgreSQL/9.3/lib/postgresql
--with-pgincludeserverdir=/opt/PostgreSQL/9.3/include/postgresql/server/
--with-pgsharedir=/opt/PostgreSQL/9.3/share
make
make install

2. Replikationsskripte erstellen und ausführen
Um die Replikation einzurichten, müssen wir einige Skripte erstellen, die sich um die Replikation kümmern, einschließlich Switchover/Switchback.

1. initialize.slonik – Dieses Skript enthält die Verbindungsinformationen der Origin/Subscriber-Knoten.
2. create_set.slonik – Dieses Skript enthält alle Origin-PK-Tabellen, die auf den Abonnentenknoten repliziert werden.
3. scribe_set.slonik – Dieses Skript beginnt mit der Replikation von Set-Daten zum Abonnentenknoten.
4. switchover.slonik – Dieses Skript hilft, die Kontrolle von Origin auf Subscriber zu übertragen.
5. switchback.slonik – Dieses Skript hilft bei der Fallback-Steuerung vom Abonnenten zu Origin.

Zum Schluss zwei weitere Startskripte „start_OriginNode.sh“ und "start_SubscriberNode.sh" das startet slon-Prozesse gemäß den Binärdateien, die auf Origin/Subscriber-Knoten kompiliert wurden.

Laden Sie hier alle Skripte herunter.

Hier sind die Beispieldaten auf dem Ursprungsknoten (8.4.22) in der Foo-Tabelle mit einer Spalte des Datentyps bytea, die wir mit Hilfe der erstellten Skripts auf den Abonnentenknoten (9.3.5) replizieren werden.

masterdb=# select * from foo;
id | name | image
----+----------------------+-------
1 | Raghav | test1
2 | Rao | test2
3 | Rags | test3
(3 rows)

Rufen wir die Skripts nacheinander auf, um die Replikation einzurichten. DENKEN SIE DARAN, DASS ALLE SLONIK-SKRIPT NUR AUF DEM ORIGIN-KNOTEN AUSGEFÜHRT WERDEN SOLLTEN, MIT AUSNAHME VON „start_OriginNode.sh“ UND „start_SubscriberNode.sh“, DIE EINZELN AUSGEFÜHRT WERDEN SOLLTEN.

-bash-4.1$ slonik initalize.slonik
-bash-4.1$ slonik create_set.slonik
create_set.slonik:13: Set 1 ...created
create_set.slonik:16: PKey table *** public.foo *** added.
-bash-4.1$ sh start_OriginNode.sh
-bash-4.1$ sh start_SubscriberNode.sh //ON SUBSCRIBER NODE
-bash-4.1$ slonik subscribe_set.slonik

Nach erfolgreicher Ausführung des obigen Skripts können Sie feststellen, dass die Daten von Origin (masterdb) auf Subscriber (slavedb) repliziert wurden. Außerdem wird kein DML-Vorgang auf dem Abonnentenknoten zugelassen:

slavedb=# select * from foo;
id | name | image
----+----------------------+-------
1 | Raghav | test1
2 | Rao | test2
3 | Rags | test3
(3 rows)

slavedb=# insert into foo values (4,'PG-Experts','Image2');
ERROR: Slony-I: Table foo is replicated and cannot be modified on a subscriber node - role=0

Cool… Wir haben Daten auf die neuere Version von PostgreSQL 9.3.5 verschoben. Wenn Sie zu diesem Zeitpunkt der Meinung sind, dass alle Daten auf den Abonnentenknoten repliziert wurden, können Sie umschalten.

3. Umschaltung/Rückschaltung testen.

Lassen Sie uns mit dem Skript auf die neueste Version umschalten und versuchen, Daten auf Abonnenten-/Ursprungsknoten einzufügen.

-bash-4.1$ slonik switchover.slonik
switchover.slonik:8: Set 1 has been moved from Node 1 to Node 2

slavedb=# insert into foo values (4,'PG-Experts','Image2');
INSERT 0 1

masterdb=# select * from foo ;
id | name | image
----+----------------------+-------
1 | Raghav | test1
2 | Rao | test2
3 | Rags | test3
4 | PG-Experts | Image2
(4 rows)

masterdb=# insert into foo values (5,'PG-Experts','Image3');
ERROR: Slony-I: Table foo is replicated and cannot be modified on a subscriber node - role=0

Perfekt ... Das ist, was wir suchen, jetzt Slavedb (Subscriber Node), auf dem die PG 9.3.5-Version ausgeführt wird, die Daten akzeptiert, und Masterdb (Origin Node), der die Slavedb-Daten empfängt. Auch die Ablehnung von DMLs, die auf masterdb ausgeführt werden.

Slony-I-Protokolle zeigen die Bewegungen der Ursprungs-/Abonnenten-Knoten-ID zum Zeitpunkt der Umschaltung:

2014-12-12 04:55:06 PST CONFIG moveSet: set_id=1 old_origin=1 new_origin=2
2014-12-12 04:55:06 PST CONFIG storeListen: li_origin=1 li_receiver=2 li_provider=1
2014-12-12 04:55:06 PST CONFIG remoteWorkerThread_1: update provider configuration
2014-12-12 04:55:06 PST CONFIG remoteWorkerThread_1: helper thread for provider 1 terminated
2014-12-12 04:55:06 PST CONFIG remoteWorkerThread_1: disconnecting from data provider 1
...
...
2014-12-12 04:55:11 PST INFO start processing ACCEPT_SET
2014-12-12 04:55:11 PST INFO ACCEPT: set=1
2014-12-12 04:55:11 PST INFO ACCEPT: old origin=1
2014-12-12 04:55:11 PST INFO ACCEPT: new origin=2
2014-12-12 04:55:11 PST INFO ACCEPT: move set seq=5000006393
2014-12-12 04:55:11 PST INFO got parms ACCEPT_SET
erhalten

Wenn Sie zu diesem Zeitpunkt auf Probleme stoßen, können Sie zu einer älteren Version zurückkehren. Nach dem Zurückschalten können Sie mit der älteren Version fortfahren, bis Ihre Anwendung oder andere Probleme behoben sind. Dies ist der perfekte Rollback-Plan, ohne viel Zeit bei Problemen nach der Umstellung zu verschwenden..

-bash-4.1$ slonik switchback.slonik
switchback.slonik:8: Set 1 has been moved from Node 2 to Node 1

slavedb=# insert into foo values (5,'PG-Experts','Image3');
ERROR: Slony-I: Table foo is replicated and cannot be modified on a subscriber node - role=0

masterdb=# insert into foo values (5,'PG-Experts','Image3');
INSERT 0 1

slavedb=# select * from foo ;
id | name | image
----+----------------------+-------
1 | Raghav | test1
2 | Rao | test2
3 | Rags | test3
4 | PG-Experts | Image2
5 | PG-Experts | Image3
(5 rows)

Sehr schön…!!! Ist das nicht genau das Rollback mit minimaler Ausfallzeit? Ja, es ist ein perfekter Wechsel zwischen Knoten, ohne eine Transaktion zu verpassen.

Protokolle, die den Wechsel vom Abonnenten zum Ursprungsknoten zeigen:

2014-12-12 04:58:45 PST CONFIG moveSet: set_id=1 old_origin=2 new_origin=1
2014-12-12 04:58:45 PST CONFIG storeListen: li_origin=2 li_receiver=1 li_provider=2
2014-12-12 04:58:45 PST CONFIG remoteWorkerThread_2: update provider configuration
2014-12-12 04:58:45 PST CONFIG remoteWorkerThread_2: helper thread for provider 2 terminated
2014-12-12 04:58:45 PST CONFIG remoteWorkerThread_2: disconnecting from data provider 2
2014-12-12 04:58:46 PST CONFIG storeListen: li_origin=2 li_receiver=1 li_provider=2
...
...
2014-12-12 04:58:47 PST INFO start processing ACCEPT_SET
2014-12-12 04:58:47 PST INFO ACCEPT: set=1
2014-12-12 04:58:47 PST INFO ACCEPT: old origin=2
2014-12-12 04:58:47 PST INFO ACCEPT: new origin=1
2014-12-12 04:58:47 PST INFO ACCEPT: move set seq=5000006403
2014-12-12 04:58:47 PST INFO got parms ACCEPT_SET
2014-12-12 04:58:48 PST CONFIG moveSet: set_id=1 old_origin=2 new_origin=1

Zu diesem Zeitpunkt haben Sie vielleicht bemerkt, dass keine der Transaktionen während des Wechselvorgangs zwischen den PostgreSQL-Versionen verloren geht. Lediglich die Ausfallzeit kann Ihre Anwendung zum Starten/Stoppen für die Verbindung mit Ursprungs- und Abonnentenknoten sein, aber während Ursprungs-/Abonnentenknoten niemals heruntergefahren werden, sind sie einfach betriebsbereit.

Denken Sie daran, dass die hier gezeigte Methode nicht nur für Upgrades nützlich ist, sondern dieselbe Methode in Slony-I, um zwischen Knoten zu wechseln.

Vielen Dank für Ihre Geduld :). Ich hoffe, dieser Beitrag hilft Ihnen dabei, PostgreSQL mit minimaler Ausfallzeit mit Slony-I zu aktualisieren, einschließlich des richtigen Rollback-Plans.