PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Implémentation du basculement/basculement dans PostgreSQL 9.3.

Cet article explique aux DBA sophistiqués comment configurer un environnement de basculement et de basculement gracieux dans la haute disponibilité de PostgreSQL. Tout d'abord, merci aux auteurs de correctifs Heikki et Fujii pour avoir facilité le basculement/basculement dans PostgreSQL 9.3. (Pardonnez-moi si j'ai oublié d'autres noms).

Permettez-moi d'essayer de l'illustrer brièvement avant ces correctifs, vous savez tous que les veilles sont des composants essentiels pour obtenir une reprise après sinistre rapide et sûre. Dans PostgreSQL, le concept de récupération traite principalement des délais pour identifier une série de segments WAL avant et après le PITR ou la promotion de Standby pour éviter le chevauchement des segments WAL. L'ID de la chronologie est associé aux noms de fichier de segment WAL (par exemple :dans $PGDATA/pg_xlog/0000000C000000020000009E, le segment "0000000C" est l'ID de la chronologie). Dans la réplication en continu, le primaire et l'esclave suivront le même ID de chronologie, mais lorsque Standby est promu en tant que nouveau maître par le basculement, il dépasse l'ID de chronologie et l'ancien primaire refuse de redémarrer en tant que veille en raison de la différence d'ID de chronologie et renvoie le message d'erreur suivant :

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.

Ainsi, un nouveau Standby doit être construit à partir de zéro, si la taille de la base de données est énorme, la reconstruction prend plus de temps et pendant cette période, le primaire nouvellement promu fonctionnera sans Standby. Il y a aussi un autre problème comme, lorsque le basculement se produit, le primaire effectue un arrêt propre, le processus Walsender envoie tous les enregistrements WAL en attente au serveur de secours, mais il n'attend pas qu'ils soient répliqués avant de se terminer. Walreceiver ne parvient pas à appliquer ces enregistrements WAL en attente car il détecte la fermeture de la connexion et quitte.

Aujourd'hui, avec deux mises à jour logicielles clés dans PostgreSQL 9.3, les deux problèmes sont très bien résolus par les auteurs et maintenant, Streaming Replication Standby suit un changement de chronologie de manière cohérente. Nous pouvons maintenant basculer de manière transparente et sans douleur les tâches entre primaire et veille en redémarrant simplement et en réduisant considérablement le temps de reconstruction de veille.

Remarque :Basculement/Basculement impossible si les archives WAL ne sont pas accessibles aux deux serveurs et dans le processus de basculement, la base de données principale doit effectuer un arrêt propre (mode normal ou rapide).

Pour la démonstration, commençons par la configuration de Streaming Replication (wiki pour configurer SR) que j'ai configuré dans ma machine virtuelle locale entre deux clusters (5432 en tant que primaire et 5433 en veille) partageant un emplacement d'archives WAL commun, car les deux clusters doivent avoir un accès complet de séquence d'archives WAL. Regardez l'instantané partagé ci-dessous avec les détails de configuration et l'ID de la chronologie actuelle pour une meilleure compréhension du concept.

À ce stade, tout le monde doit avoir une solide compréhension que le basculement et le basculement sont des activités planifiées. Maintenant que la configuration SR est en place, nous pouvons échanger les fonctions de primaire et de secours comme indiqué ci-dessous :

Étapes de basculement :

Étape 1. Effectuez un arrêt propre de Primary[5432] (-m fast ou 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

Étape 2. Vérifiez l'état de synchronisation et l'état de récupération de Standby[5433] avant de le promouvoir :

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

Veille en synchronisation complète. À ce stade, nous pouvons le promouvoir en toute sécurité en tant que principal.
Étape 3. Ouvrez le Standby en tant que nouveau primaire en faisant la promotion pg_ctl ou en créant un fichier déclencheur.

[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 a été promu en tant que maître et une nouvelle chronologie a suivi que vous pouvez remarquer dans les journaux.
Étape 4. Redémarrez l'ancien primaire en veille et laissez suivre la nouvelle chronologie en passant "recovery_target_timline='latest'" dans le fichier $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

Si vous passez par recovery.conf, il est très clair que l'ancien primaire essaie de se connecter au port 5433 en tant que nouveau standby pointant vers l'emplacement commun des archives WAL et a démarré.

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

Étape 5. Vérifiez le nouvel état de veille.

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

Cool, sans aucune réinitialisation, nous avons ramené l'ancien principal en tant que nouveau veille.

Étapes de retour :

Étape 1. Effectuez un arrêt propre du nouveau principal [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

Étape 2. Vérifiez l'état de synchronisation de la nouvelle veille [5432] avant la promotion.
Étape 3. Ouvrez le nouveau Standby [5432] en tant que principal en créant un fichier déclencheur ou une promotion pg_ctl.

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

Étape 4. Redémarrez le nouveau primaire [5433] arrêté en tant que nouveau 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

Vous pouvez vérifier les journaux de la nouvelle mise en veille.

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

Très bien, sans trop de temps, nous avons inversé les tâches des serveurs principal et de secours. Vous pouvez même remarquer l'augmentation des ID de chronologie à partir des journaux pour chaque promotion.

Comme d'autres, tous mes messages font partie du partage des connaissances, tous les commentaires ou corrections sont les bienvenus. 🙂