sql >> Database >  >> RDS >> PostgreSQL

Omschakeling/Switchback implementeren in PostgreSQL 9.3.

Dit bericht leert geavanceerde DBA's over het opzetten van een sierlijke Switchover- en Switchback-omgeving in PostgreSQL met hoge beschikbaarheid. Ten eerste, dank aan patch-auteurs Heikki en Fujii voor het gemakkelijker maken van Switchover/Switchback in PostgreSQL 9.3. (Pardon als ik andere namen heb gemist).

Laat me proberen het kort te illustreren voorafgaand aan deze patches, jullie weten allemaal dat Standby's cruciale componenten zijn voor snel en veilig noodherstel. In PostgreSQL heeft het herstelconcept voornamelijk te maken met tijdlijnen om een ​​reeks WAL-segmenten voor en na de PITR te identificeren of om stand-by te promoten om overlapping van WAL-segmenten te voorkomen. Tijdlijn-ID's zijn gekoppeld aan WAL-segmentbestandsnamen (bijvoorbeeld:- In $PGDATA/pg_xlog/0000000C000000020000009E is segment "0000000C" tijdlijn-ID). In Streaming Replication zullen zowel Primary als Slave dezelfde tijdlijn-ID volgen, maar wanneer Standby promotie krijgt als nieuwe master door Switchover, wordt de tijdlijn-ID gestoten en oude Primary weigert opnieuw te starten als Standby vanwege tijdlijn-ID-verschil en foutmelding als:

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.

Dus een nieuwe Standby moet helemaal opnieuw worden gebouwd, als de database enorm groot is, duurt het langer om opnieuw op te bouwen en gedurende deze periode zal de nieuw gepromote Primary draaien zonder Standby. Er is ook een ander probleem, zoals wanneer de omschakeling plaatsvindt. Primair wordt afgesloten, het Walsender-proces stuurt alle openstaande WAL-records naar de stand-by, maar het wacht niet tot ze zijn gerepliceerd voordat het wordt afgesloten. Walreceiver past die openstaande WAL-records niet toe omdat het de verbinding met de verbinding en het afsluiten detecteert.

Tegenwoordig, met twee belangrijke software-updates in PostgreSQL 9.3, zijn beide problemen zeer goed aangepakt door auteurs en nu volgen Streaming Replication Standby's consequent een tijdlijnwisseling. We kunnen nu naadloos en pijnloos de taken wisselen tussen primair en stand-by door gewoon opnieuw op te starten en de herbouwtijd van stand-by aanzienlijk te verkorten.

Opmerking:Overschakelen/terugschakelen is niet mogelijk als WAL-archieven niet toegankelijk zijn voor beide servers en in het omschakelingsproces. Primaire database moet schoon worden afgesloten (normale of snelle modus).

Laten we voor de demo beginnen met het instellen van Streaming Replication (wiki om SR in te stellen) die ik heb geconfigureerd in mijn lokale VM tussen twee clusters (5432 als primair en 5433 als stand-by) die een gemeenschappelijke WAL-archievenlocatie delen, omdat beide clusters volledige toegang moeten hebben volgorde van WAL-archieven. Bekijk de snapshot die hieronder is gedeeld met details over de instellingen en de huidige tijdlijn-ID voor een beter begrip van het concept.

In dit stadium moet iedereen een goed begrip hebben dat Switchover en Switchback geplande activiteiten zijn. Nu SR is ingesteld, kunnen we de taken van primair en stand-by uitwisselen, zoals hieronder weergegeven:

Overstapstappen:

Stap 1. Voer een schone afsluiting uit van Primair [5432] (-m snel of slim)

[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

Stap 2. Controleer de synchronisatiestatus en herstelstatus van Standby[5433] voordat u deze promoot:

[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)

Stand-by in volledige synchronisatie. In dit stadium kunnen we het veilig promoten als Primair.
Stap 3. Open de stand-by als nieuw primair door pg_ctl te promoten of een triggerbestand te maken.

[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 is gepromoot als master en er is een nieuwe tijdlijn gevolgd die je kunt zien in logs.
Stap 4. Start de oude Primary opnieuw als stand-by en laat de nieuwe tijdlijn volgen door "recovery_target_timline='latest'" door te geven in het $PGDATA/recovery.conf-bestand.

[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

Als je recovery.conf doorloopt, is het heel duidelijk dat de oude primaire probeert verbinding te maken met de 5433-poort als nieuwe stand-by die verwijst naar de algemene WAL-archievenlocatie en is begonnen.

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

Stap 5. Controleer de nieuwe 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, zonder enige herconfiguratie hebben we de oude Primary teruggebracht naar de nieuwe Standby.

Terugschakelen:

Stap 1. Voer schone afsluiting van nieuwe primaire [5433] uit:

[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

Stap 2. Controleer de synchronisatiestatus van de nieuwe stand-by [5432] voordat u gaat promoveren.
Stap 3. Open de nieuwe stand-by [5432] als primair door een triggerbestand te maken of pg_ctl te promoten.

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

Stap 4. Opnieuw opstarten stopte nieuwe primaire [5433] als nieuwe stand-by.

[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

U kunt de logboeken van nieuwe Standby controleren.

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

Heel fijn, zonder veel tijd hebben we de taken van Primary en Standby servers omgewisseld. U kunt zelfs de toename van de tijdlijn-ID's van logs voor elke promotie zien.

Net als anderen maken al mijn berichten deel uit van het delen van kennis, opmerkingen of correcties zijn van harte welkom.


  1. Vreemd gedrag in Postgresql

  2. UnicodeEncodeError:'latin-1' codec kan geen teken coderen

  3. Inzicht in 'datetimeoffset' opslaggrootte in SQL Server

  4. Krijg n gegroepeerde categorieën en tel anderen op tot één