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

Implementieren von Switchover/Switchback in PostgreSQL 9.3.

Dieser Beitrag schult erfahrene DBAs in der Einrichtung einer eleganten Switchover- und Switchback-Umgebung in PostgreSQL-Hochverfügbarkeit. Zunächst danke an die Patch-Autoren Heikki und Fujii, die Switchover/Switchback in PostgreSQL 9.3 einfacher gemacht haben. (Verzeihen Sie, wenn ich andere Namen übersehen habe).

Lassen Sie mich versuchen, es kurz vor diesen Patches zu veranschaulichen. Sie alle wissen, dass Standbys kritische Komponenten sind, um eine schnelle und sichere Notfallwiederherstellung zu erreichen. In PostgreSQL befasst sich das Wiederherstellungskonzept hauptsächlich mit Zeitplänen, um eine Reihe von WAL-Segmenten vor und nach dem PITR oder der Heraufstufung von Standby zu identifizieren, um eine Überlappung von WAL-Segmenten zu vermeiden. Zeitleisten-IDs sind WAL-Segmentdateinamen zugeordnet (z. B.:In $PGDATA/pg_xlog/0000000C000000020000009E ist Segment „0000000C“ die Zeitleisten-ID). Bei der Streaming-Replikation folgen sowohl der Primär- als auch der Slave derselben Zeitachsen-ID. Wenn Standby jedoch durch Switchover zum neuen Master befördert wird, wird die Zeitachsen-ID angestoßen und die alte Primärdatenbank weigert sich, als Standby neu zu starten, da sich die Zeitachsen-ID unterscheidet, und eine Fehlermeldung wie folgt ausgibt:

FATAL:  requested timeline 10 is not a child of this server's history
DETAIL: Latest checkpoint is at 2/9A000028 on timeline 9, but in the history of the requested timeline, the server forked off from that timeline at 2/99017E68.

Daher muss ein neues Standby von Grund auf neu erstellt werden, wenn die Datenbankgröße sehr groß ist, dauert die Wiederherstellung länger, und für diesen Zeitraum wird neu heraufgestufte primäre Datenbank ohne Standby ausgeführt. Es gibt auch ein anderes Problem, z. B. wenn beim Switchover der primäre Prozess sauber heruntergefahren wird, sendet der Walsender-Prozess alle ausstehenden WAL-Einträge an den Standby, wartet aber nicht darauf, dass sie repliziert werden, bevor er beendet wird. Walreceiver kann diese ausstehenden WAL-Datensätze nicht anwenden, da er die Schließung der Verbindung erkennt und beendet.

Heute, mit zwei wichtigen Software-Updates in PostgreSQL 9.3, werden beide Probleme von Autoren sehr gut angegangen, und jetzt folgen Streaming Replication Standbys konsequent einem Zeitachsenwechsel. Wir können jetzt nahtlos und schmerzlos die Aufgaben zwischen Primär und Standby wechseln, indem wir einfach neu starten und die Wiederherstellungszeit von Standby erheblich verkürzen.

Hinweis:Switchover/Switchback nicht möglich, wenn WAL-Archive nicht für beide Server zugänglich sind und die primäre Datenbank im Switchover-Prozess sauber heruntergefahren werden muss (normaler oder schneller Modus).

Beginnen wir zur Demo mit der Einrichtung der Streaming-Replikation (Wiki zur Einrichtung von SR), die ich in meiner lokalen VM zwischen zwei Clustern (5432 als primär und 5433 als Standby) konfiguriert habe, die sich einen gemeinsamen WAL-Archivspeicherort teilen, da beide Cluster vollständigen Zugriff haben sollten der Reihenfolge der WAL-Archive. Sehen Sie sich den unten geteilten Schnappschuss mit Einrichtungsdetails und aktueller Timeline-ID an, um das Konzept besser zu verstehen.

In dieser Phase muss jeder ein solides Verständnis dafür haben, dass Switchover und Switchback geplante Aktivitäten sind. Jetzt, wo die SR eingerichtet ist, können wir die Pflichten von Primär und Standby wie unten gezeigt austauschen:

Umschaltschritte:

Schritt 1. Führen Sie einen sauberen Shutdown von Primary durch[5432] (-m fast oder smart)

[postgres@localhost:/~]$ /opt/PostgreSQL/9.3/bin/pg_ctl -D /opt/PostgreSQL/9.3/data stop -mf
waiting for server to shut down.... done
server stopped

Schritt 2. Überprüfen Sie den Synchronisierungsstatus und den Wiederherstellungsstatus von Standby[5433], bevor Sie ihn heraufstufen:

[postgres@localhost:/opt/PostgreSQL/9.3~]$  psql -p 5433 -c 'select pg_last_xlog_receive_location() "receive_location",
pg_last_xlog_replay_location() "replay_location",
pg_is_in_recovery() "recovery_status";'
receive_location | replay_location | recovery_status
------------------+-----------------+-----------------
2/9F000A20 | 2/9F000A20 | t
(1 row)

Standby in vollständiger Synchronisation. In diesem Stadium können wir es sicher als primäres Konto heraufstufen.
Schritt 3. Öffnen Sie den Standby als neuen Primären, indem Sie pg_ctl promoten oder eine Triggerdatei erstellen.

[postgres@localhost:/opt/PostgreSQL/9.3~]$ grep trigger_file data_slave/recovery.conf
trigger_file = '/tmp/primary_down.txt'
[postgres@localhost:/opt/PostgreSQL/9.3~]$ touch /tmp/primary_down.txt

[postgres@localhost:/opt/PostgreSQL/9.3~]$ psql -p 5433 -c "select pg_is_in_recovery();"
pg_is_in_recovery
-------------------
f
(1 row)

In Logs:
2014-12-29 00:16:04 PST-26344-- [host=] LOG: trigger file found: /tmp/primary_down.txt
2014-12-29 00:16:04 PST-26344-- [host=] LOG: redo done at 2/A0000028
2014-12-29 00:16:04 PST-26344-- [host=] LOG: selected new timeline ID: 14
2014-12-29 00:16:04 PST-26344-- [host=] LOG: restored log file "0000000D.history" from archive
2014-12-29 00:16:04 PST-26344-- [host=] LOG: archive recovery complete
2014-12-29 00:16:04 PST-26342-- [host=] LOG: database system is ready to accept connections
2014-12-29 00:16:04 PST-31874-- [host=] LOG: autovacuum launcher started

Standby wurde zum Master hochgestuft und es folgte eine neue Zeitachse, die Sie in den Protokollen sehen können.
Schritt 4. Starten Sie die alte Primäre als Standby neu und erlauben Sie, der neuen Zeitachse zu folgen, indem Sie „recovery_target_timline=’latest'“ in der Datei $PGDATA/recovery.conf übergeben.

[postgres@localhost:/opt/PostgreSQL/9.3~]$ cat data/recovery.conf
recovery_target_timeline = 'latest'
standby_mode = on
primary_conninfo = 'host=localhost port=5433 user=postgres'
restore_command = 'cp /opt/PostgreSQL/9.3/archives93/%f %p'
trigger_file = '/tmp/primary_131_down.txt'
[postgres@localhost:/opt/PostgreSQL/9.3~]$ /opt/PostgreSQL/9.3/bin/pg_ctl -D /opt/PostgreSQL/9.3/data start
server starting

Wenn Sie die recovery.conf durchgehen, wird deutlich, dass der alte Primärserver versucht, sich mit dem Port 5433 als neuer Standby-Server zu verbinden, der auf den gemeinsamen Speicherort des WAL-Archivs verweist und gestartet wurde.

In Logs:
2014-12-29 00:21:17 PST-32315-- [host=] LOG: database system was shut down at 2014-12-29 00:12:23 PST
2014-12-29 00:21:17 PST-32315-- [host=] LOG: restored log file "0000000E.history" from archive
2014-12-29 00:21:17 PST-32315-- [host=] LOG: entering standby mode
2014-12-29 00:21:17 PST-32315-- [host=] LOG: restored log file "0000000D00000002000000A0" from archive
2014-12-29 00:21:17 PST-32315-- [host=] LOG: restored log file "0000000D.history" from archive
2014-12-29 00:21:17 PST-32315-- [host=] LOG: consistent recovery state reached at 2/A0000090
2014-12-29 00:21:17 PST-32315-- [host=] LOG: record with zero length at 2/A0000090
2014-12-29 00:21:17 PST-32310-- [host=] LOG: database system is ready to accept read only connections
2014-12-29 00:21:17 PST-32325-- [host=] LOG: started streaming WAL from primary at 2/A0000000 on timeline 14

Schritt 5. Überprüfen Sie den neuen Standby-Status.

[postgres@localhost:/opt/PostgreSQL/9.3~]$ psql -p 5432 -c "select pg_is_in_recovery();"
pg_is_in_recovery
-------------------
t
(1 row)

Cool, ohne Neuinstallation haben wir den alten Primary als neuen Standby zurückgebracht.

Wechselschritte:

Schritt 1. Führen Sie ein sauberes Herunterfahren des neuen Primary durch [5433]:

[postgres@localhost:/opt/~]$ /opt/PostgreSQL/9.3/bin/pg_ctl -D /opt/PostgreSQL/9.3/data_slave stop -mf
waiting for server to shut down.... done
server stopped

Schritt 2. Überprüfen Sie den Synchronisierungsstatus des neuen Standby [5432], bevor Sie ihn heraufstufen.
Schritt 3. Öffnen Sie das neue Standby [5432] als Primär, indem Sie eine Triggerdatei erstellen oder pg_ctl promote.

[postgres@localhost:/opt/PostgreSQL/9.3~]$ touch /tmp/primary_131_down.txt

Schritt 4. Neustart gestoppt neu Primary [5433] als neuer Standby.

[postgres@localhost:/opt/PostgreSQL/9.3~]$ more data_slave/recovery.conf
recovery_target_timeline = 'latest'
standby_mode = on
primary_conninfo = 'host=localhost port=5432 user=postgres'
restore_command = 'cp /opt/PostgreSQL/9.3/archives93/%f %p'
trigger_file = '/tmp/primary_down.txt'

[postgres@localhost:/opt/PostgreSQL/9.3~]$ /opt/PostgreSQL/9.3/bin/pg_ctl -D /opt/PostgreSQL/9.3/data_slave start
server starting

Sie können die Protokolle des neuen Standby überprüfen.

In logs:
[postgres@localhost:/opt/PostgreSQL/9.3/data_slave/pg_log~]$ more postgresql-2014-12-29_003655.log
2014-12-29 00:36:55 PST-919-- [host=] LOG: database system was shut down at 2014-12-29 00:34:01 PST
2014-12-29 00:36:55 PST-919-- [host=] LOG: restored log file "0000000F.history" from archive
2014-12-29 00:36:55 PST-919-- [host=] LOG: entering standby mode
2014-12-29 00:36:55 PST-919-- [host=] LOG: restored log file "0000000F.history" from archive
2014-12-29 00:36:55 PST-919-- [host=] LOG: restored log file "0000000E00000002000000A1" from archive
2014-12-29 00:36:55 PST-919-- [host=] LOG: restored log file "0000000E.history" from archive
2014-12-29 00:36:55 PST-919-- [host=] LOG: consistent recovery state reached at 2/A1000090
2014-12-29 00:36:55 PST-919-- [host=] LOG: record with zero length at 2/A1000090
2014-12-29 00:36:55 PST-914-- [host=] LOG: database system is ready to accept read only connections
2014-12-29 00:36:55 PST-929-- [host=] LOG: started streaming WAL from primary at 2/A1000000 on timeline 15
2014-12-29 00:36:56 PST-919-- [host=] LOG: redo starts at 2/A1000090

Sehr schön, ohne viel Zeitaufwand haben wir die Aufgaben von Primär- und Standby-Servern getauscht. Sie können sogar die Erhöhung der Timeline-IDs aus den Protokollen für jede Werbeaktion erkennen.

Wie andere sind alle meine Beiträge Teil des Wissensaustauschs, Kommentare oder Korrekturen sind sehr willkommen. 🙂