sql >> Database teknologi >  >> RDS >> PostgreSQL

Implementering af Switchover/Switchback i PostgreSQL 9.3.

Dette indlæg uddanner sofistikerede DBA'er i, hvordan man opsætter et yndefuldt Switchover- og Switchback-miljø i PostgreSQL høj tilgængelighed. For det første tak til patchforfatterne Heikki og Fujii for at gøre omskiftning/omskiftning nemmere i PostgreSQL 9.3.(Tilgiv mig, hvis jeg savnede andre navne).

Lad mig forsøge at illustrere det kort før disse programrettelser. I ved alle, at Standby's er kritiske komponenter for at opnå hurtig og sikker katastrofegendannelse. I PostgreSQL omhandler gendannelseskonceptet hovedsageligt tidslinjer for at identificere en række WAL-segmenter før og efter PITR eller promovering af Standby for at undgå overlapning af WAL-segmenter. Tidslinje-id er knyttet til WAL-segmentfilnavne (f.eks.:- I $PGDATA/pg_xlog/0000000C000000020000009E er segmentet "0000000C" tidslinje-id'et). I Streaming-replikering vil både Primær og Slave følge det samme tidslinje-id, men når Standby bliver forfremmet som ny master ved Switchover, støder det tidslinje-id'et, og gammel Primary nægter at genstarte som Standby på grund af tidslinje-ID-forskel og sender fejlmeddelelse 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.

Der skal således bygges en ny Standby fra bunden, hvis databasestørrelsen er enorm, så er der længere tid til at genopbygge, og i denne periode vil den nypromoverede Primary køre uden Standby. Der er også et andet problem som, når omskiftning sker. Primær lukker ned, sender Walsender-processen alle udestående WAL-poster til standby, men den venter ikke på, at de bliver replikeret, før den afsluttes. Walreceiver undlader at anvende disse udestående WAL-registreringer, da den registrerer lukning af forbindelse og udgange.

I dag, med to vigtige softwareopdateringer i PostgreSQL 9.3, følger begge de problemer, som forfattere og nu Streaming Replication Standby'er behandlet meget godt, en tidslinjeskift konsekvent. Vi kan nu problemfrit og smertefrit skifte opgaver mellem Primær og Standby ved blot at genstarte og væsentligt reducere genopbygningstiden for Standby.

Bemærk:Switchover/Switchback er ikke muligt, hvis WAL-arkiver ikke er tilgængelige for begge servere, og i overgangsprocessen skal den primære database lave ren nedlukning (normal eller hurtig tilstand).

For at demo, lad os starte med opsætning af Streaming Replication (wiki til opsætning af SR), som jeg har konfigureret i min lokale VM mellem to klynger (5432 som Primær og 5433 som Standby), der deler en fælles WAL-arkivplacering, fordi begge klynger skal have fuld adgang af rækkefølgen af ​​WAL-arkiver. Se på det øjebliksbillede, der er delt nedenfor med opsætningsdetaljer og det aktuelle tidslinje-id for bedre forståelse af konceptet.

På dette stadium skal alle have en solid forståelse af, at Switchover og Switchback er planlagte aktiviteter. Nu SR setup er på plads, kan vi udveksle pligterne primær og standby som vist nedenfor:

Skifttrin:

Trin 1. Lav en ren lukning af Primary[5432] (-m hurtig 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

Trin 2. Tjek for synkroniseringsstatus og genoprettelsesstatus for Standby[5433], før du promoverer 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 fuldstændig synkronisering. På dette stadium er vi sikre på at promovere det som primært.
Trin 3. Åbn Standby som ny Primary ved at pg_ctl promote eller oprette 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 er blevet forfremmet som master, og en ny tidslinje fulgte, som du kan se i logfiler.
Trin 4. Genstart den gamle Primary som standby og tillad at følge den nye tidslinje ved at sende "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

Hvis du går gennem recovery.conf, er det meget tydeligt, at den gamle primære forsøger at oprette forbindelse til 5433-porten som ny standby, og peger på den fælles WAL-arkivplacering og startede.

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

Trin 5. Bekræft den nye standby-status.

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

Fedt, uden nogen gen-setup har vi bragt gamle Primary tilbage som ny Standby.

Trin til at skifte tilbage:

Trin 1. Lav en ren lukning af ny Primary [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

Trin 2. Tjek for synkroniseringsstatus for ny Standby [5432] før promovering.
Trin 3. Åbn den nye Standby [5432] som Primær ved at oprette triggerfil eller pg_ctl promote.

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

Trin 4. Genstart stoppet 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 verificere logfilerne for ny 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

Meget rart, uden meget tid har vi skiftet opgaver for primære og standby-servere. Du kan endda bemærke stigningen i tidslinje-id'erne fra logfiler for hver kampagne.

Som andre er alle mine indlæg en del af videndeling, alle kommentarer eller rettelser er meget velkomne. 🙂


  1. MySQL:Kan ikke oprette tabel (fejlnr:150)

  2. Sådan optimeres PostgreSQL logisk replikering

  3. Hvordan kan jeg konvertere en SQL Server 2008 DateTimeOffset til en DateTime

  4. SQL Server HVIS IKKE FINNES Brug?