Vorrei tentare di illustrarlo in breve prima di queste patch, tutti voi sapete che gli Standby sono componenti critici per ottenere un ripristino di emergenza rapido e sicuro. In PostgreSQL, il concetto di ripristino si occupa principalmente delle linee temporali per identificare una serie di segmenti WAL prima e dopo il PITR o la promozione di Standby per evitare la sovrapposizione dei segmenti WAL. Gli ID sequenza temporale sono associati ai nomi dei file di segmento WAL (ad es.:- In $PGDATA/pg_xlog/0000000C000000020000009E il segmento "0000000C" è l'ID sequenza temporale). In Streaming Replication sia Primary che Slave seguiranno lo stesso ID sequenza temporale, tuttavia quando Standby ottiene la promozione come nuovo master tramite Switchover, aumenta l'ID sequenza temporale e il vecchio Primario si rifiuta di riavviarsi come Standby a causa della differenza di ID sequenza temporale e genera un messaggio di errore come:
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.
Pertanto, è necessario creare un nuovo Standby da zero, se la dimensione del database è enorme, è necessario un tempo più lungo per ricostruire e per questo periodo il nuovo Primario promosso funzionerà senza Standby. C'è anche un altro problema come, quando si verifica il passaggio, Primaria esegue l'arresto pulito, il processo Walsender invia tutti i record WAL in sospeso in standby ma non attende che vengano replicati prima di uscire. Walreceiver non applica i record WAL in sospeso poiché rileva la chiusura della connessione e le uscite.
Oggi, con due aggiornamenti software chiave in PostgreSQL 9.3, entrambi i problemi affrontati molto bene dagli autori e ora Streaming Replication Standby seguono costantemente un cambio di sequenza temporale. Ora possiamo passare in modo semplice e indolore dai compiti tra Primario e Standby semplicemente riavviando e riducendo notevolmente i tempi di ricostruzione di Standby.
Nota:il passaggio/ritorno non è possibile se gli archivi WAL non sono accessibili a entrambi i server e nel processo di passaggio il database primario deve eseguire uno spegnimento pulito (modalità normale o veloce).
Per fare una dimostrazione, iniziamo con l'installazione di Streaming Replication (wiki per configurare SR) che ho configurato nella mia macchina virtuale locale tra due cluster (5432 come primario e 5433 come standby) che condividono una posizione comune degli archivi WAL, perché entrambi i cluster dovrebbero avere accesso completo di sequenza degli archivi WAL. Guarda l'istantanea condivisa di seguito con i dettagli della configurazione e l'ID sequenza temporale corrente per una migliore comprensione del concetto.
In questa fase tutti devono avere una solida comprensione del fatto che Switchover e Switchback sono attività pianificate. Ora l'impostazione SR in atto, possiamo scambiare i compiti di primario e standby come mostrato di seguito:
Passaggi del passaggio:
Passaggio 1. Esegui lo spegnimento pulito del Primario[5432] (-m veloce o intelligente)
[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
Passaggio 2. Verifica lo stato di sincronizzazione e di ripristino di Standby[5433] prima di promuoverlo:
[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 completa sincronizzazione. A questo punto siamo sicuri di promuoverlo come Primario.
Fase 3. Apri lo Standby come nuovo primario tramite pg_ctl promuovi o creando un file trigger.
[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 è stato promosso come master ed è seguita una nuova sequenza temporale che puoi notare nei log.
Passaggio 4. Riavvia il vecchio Primary come standby e consenti di seguire la nuova timeline passando "recovery_target_timline='latest'" nel file $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
Se si esegue recovery.conf è molto chiaro che il vecchio Primary tenta di connettersi alla porta 5433 come nuovo Standby che punta alla posizione comune degli archivi WAL e viene avviato.
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
Passaggio 5. Verifica il nuovo stato di Standby.
[postgres@localhost:/opt/PostgreSQL/9.3~]$ psql -p 5432 -c "select pg_is_in_recovery();"
pg_is_in_recovery
-------------------
t
(1 row)
Fantastico, senza alcuna reimpostazione abbiamo riportato la vecchia Primaria come nuova Standby.
Passaggi per il ritorno:
Passaggio 1. Spegnimento pulito del nuovo Primario [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
Passaggio 2. Verifica lo stato di sincronizzazione del nuovo Standby [5432] prima di promuovere.
Passaggio 3. Apri il nuovo Standby [5432] come principale creando un file trigger o promuovi pg_ctl.
[postgres@localhost:/opt/PostgreSQL/9.3~]$ touch /tmp/primary_131_down.txt
Passaggio 4. Il riavvio ha interrotto il nuovo Primario [5433] come nuovo 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
Puoi verificare i log del nuovo 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
Molto bello, senza molto tempo abbiamo cambiato le funzioni dei server Primari e Standby. Puoi anche notare l'incremento degli ID della sequenza temporale dai registri per ogni promozione.
Come altri, tutti i miei post fanno parte della condivisione della conoscenza, qualsiasi commento o correzione è il benvenuto. 🙂