sql >> Databasteknik >  >> RDS >> PostgreSQL

Implementera Switchover/Switchback i PostgreSQL 9.3.

Det här inlägget utbildar sofistikerade DBA:er om hur man ställer in en elegant Switchover och Switchback-miljö i PostgreSQL hög tillgänglighet. För det första, tack till patchförfattarna Heikki och Fujii för att de har gjort omställning/växling enklare i PostgreSQL 9.3.(Ursäkta mig om jag missade andra namn).

Låt mig försöka illustrera det kort innan dessa patchar, alla ni vet att Standby är kritiska komponenter för att uppnå snabb och säker katastrofåterställning. I PostgreSQL handlar återställningskonceptet huvudsakligen om tidslinjer för att identifiera en serie WAL-segment före och efter PITR eller främjande av Standby för att undvika överlappning av WAL-segment. Tidslinje-ID är associerat med WAL-segmentfilnamn (t.ex.:- I $PGDATA/pg_xlog/0000000C000000020000009E är segmentet "0000000C" tidslinje-ID). I strömmande replikering kommer både Primär och Slave att följa samma tidslinje-ID, men när Standby får befordran som ny master genom Switchover stöter det tidslinje-ID:t och gamla Primary vägrar starta om som Standby på grund av skillnad i tidslinje-ID och skickar felmeddelande som:

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.

Således måste en ny Standby byggas från grunden, om databasstorleken är enorm så kommer en längre tid att återuppbyggas och under denna period kommer nyuppförda Primary att köras utan Standby. Det finns också ett annat problem som, när övergången sker Primär gör ren avstängning, Walsender-processen skickar alla utestående WAL-poster till standby men den väntar inte på att de ska replikeras innan den avslutas. Walreceiver misslyckas med att tillämpa dessa utestående WAL-poster eftersom den upptäcker stängning av anslutning och utgångar.

Idag, med två viktiga mjukvaruuppdateringar i PostgreSQL 9.3, följer båda problemen mycket väl av författare och nu Streaming Replication Standbys en tidslinjeväxling konsekvent. Vi kan nu sömlöst och smärtfritt byta uppgifter mellan primär och standby genom att bara starta om och kraftigt minska återuppbyggnadstiden för standby.

Obs:Övergång/Switchback är inte möjlig om WAL-arkiv inte är tillgängliga för båda servrarna och i övergångsprocessen måste den primära databasen göra ren avstängning (normalt eller snabbt läge).

För att demo, låt oss börja med installationen av Streaming Replication (wiki to setup SR) som jag har konfigurerat i min lokala virtuella dator mellan två kluster (5432 som primära och 5433 som standby) som delar en gemensam WAL-arkivplats, eftersom båda klustren ska ha fullständig åtkomst av sekvensen av WAL-arkiv. Titta på ögonblicksbilden som delas nedan med inställningsdetaljer och aktuellt tidslinje-ID för bättre förståelse av konceptet.

I detta skede måste alla ha en solid förståelse för att Switchover och Switchback är planerade aktiviteter. Nu SR setup på plats kan vi byta uppgifterna primär och standby som visas nedan:

Växlingssteg:

Steg 1. Gör en ren avstängning av Primary[5432] (-m snabb eller 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

Steg 2. Kontrollera synkroniseringsstatus och återställningsstatus för Standby[5433] innan du marknadsför det:

[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 i fullständig synk. I det här skedet är vi säkra att marknadsföra det som primärt.
Steg 3. Öppna Standby som ny Primary genom att pg_ctl promote eller skapa en triggerfil.

[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 har marknadsförts som master och en ny tidslinje följde som du kan lägga märke till i loggar.
Steg 4. Starta om gamla primära som vänteläge och låt följa den nya tidslinjen genom att skicka "recovery_target_timline='latest'" i filen $PGDATA/recovery.conf.

[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

Om du går igenom recovery.conf är det mycket tydligt att gamla Primary försöker ansluta till 5433-porten som ny Standby pekar på den vanliga WAL Archives-platsen och startade.

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

Steg 5. Verifiera den nya standby-statusen.

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

Coolt, utan någon ominstallation har vi tagit tillbaka gamla Primary som nytt Standby.

Återkopplingssteg:

Steg 1. Gör ren avstängning av nya primära [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

Steg 2. Kontrollera om det finns synkroniseringsstatus för nya Standby [5432] innan du marknadsför.
Steg 3. Öppna den nya Standby [5432] som primär genom att skapa triggerfil eller pg_ctl promote.

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

Steg 4. Omstart stoppad ny Primär [5433] som ny 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

Du kan verifiera loggarna för nya Standby.

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

Mycket trevligt, utan mycket tid har vi bytt uppgifter för primära och standby-servrar. Du kan till och med märka ökningen av tidslinje-ID:n från loggar för varje kampanj.

Liksom andra är alla mina inlägg en del av kunskapsdelning, alla kommentarer eller korrigeringar är välkomna. 🙂


  1. Hur LOWER() fungerar i MariaDB

  2. 2 sätt att skapa en tabell på en länkad server med T-SQL

  3. Fler av mina favoritpostgreSQL-frågor - och varför de också är viktiga

  4. Android JDBC fungerar inte:ClassNotFoundException på drivrutinen