18
0
Fork 0
wiki/HowtoPostgreSQLStreamingRep...

10 KiB

Cette page a été importée automatiquement de notre ancien wiki mais n'a pas encore été révisée.

Streaming Replication avec PostgreSQL

La réplication en flux (Streaming Replication) est disponible à partir de la version 9.0 de PostgreSQL.

Néanmoins, tout ce qui suit se rapporte à la version 9.2 (dernière en date), qui apporte plusieurs améliorations sur la réplication.

Caractéristiques

  • Réplication de type asynchrone (le maître et l'esclave peuvent ne pas être synchro à un instant t) ou synchrone (une transaction est commitée uniquement si elle a pu être écrite sur le maître et envoyé à l'esclave) ;
  • réplication basée sur les journaux binaires générés par PostgreSQL (WAL, pour Write Ahead Log) ;
  • réplication de l'intégralité des données et structures (toutes les bases de données sont répliquées, avec leurs tables et leurs données, pas de granularité possible). Cette fonctionnalité commencera à être introduite à partir de la 9.3 ;
  • le serveur jouant le rôle d'esclave ne peut être interrogé qu'en lecture ;
  • possibilité de mettre en cascade plusieurs esclaves.

Par rapport au mode de réplication Hot Standby, l'avantage avec la réplication en flux est qu'il n'est pas besoin d'attendre qu'un journal soit plein et fermé pour qu'il soit communiquer au serveur esclave. À l'inverse cela introduit une légère charge supplémentaire (au niveau CPU) puisqu'un (ou plusieurs) processus supplémentaire doit tourner sur le maître (wal_senders).

Pré-requis

Pré-requis pour pouvoir mettre en place une infra avec 1 maître et 1 esclave :

  • même architecture (32 bits/64 bits) sur les 2 serveur ;
  • même version majeure de PostgreSQL sur les 2 serveur (même version mineure est conseillé) ;

Installation de PostgreSQL 9.2

Sous Debian Wheezy, installation depuis le dépôt Debian de PostgreSQL :

# echo "deb <http://apt.postgresql.org/pub/repos/apt/> wheezy-pgdg main" >/etc/apt/sources.list.d/wheezy-pgdg.list
# echo "Package: postgresql-9.2 postgresql-client-common postgresql-common libpq5
> Pin: release a=wheezy-pgdg
> Pin-Priority: 999" >/etc/apt/preferences.d/postgresql
# wget --quiet -O - <http://apt.postgresql.org/pub/repos/apt/ACCC4CF8.asc> |apt-key add -
# aptitude update
# aptitude install postgresql-9.2 postgresql-contrib-9.2

Les paquets sont maintenus par les mêmes développeurs que sur Debian et Ubuntu, et les mises à jours de sécurité/corrections de bugs y sont faites régulièrement. La raison pour laquelle le dépôt est distinct du projet Debian est dû au fait qu'il a pour but de fournir plusieurs version de PostgreSQL pour une même version de Debian.

Configuration du serveur maître

Cette configuration est relative au serveur maître, mais elle doit également être reprise à l'identique sur le serveur esclave, dans le cas où les rôles doivent être échangés (suite à un failover/switchover).

Décommenter ou ajouter les directives suivantes dans le fichier /etc/postgresql/9.2/main/postgresql.conf :

# Nécessaire pour que l'esclave puisse se connecter.
listen_addresses = '*'

# Nombre maximum de processus walsender à lancer (mettre au moins le même
# nombre que de serveur esclave qui se connecteront dessus + 1 (reconnexions,
# maintenance...).
# (1 processus = 1 connexion)
max_wal_senders = 2

# « niveau de verbosité » des journaux PostgreSQL. Le niveau maximum est
# nécessaire (hot_standby) pour que l'esclave soit accessible en lecture.
wal_level = hot_standby

# Activation de l'archivage des WAL. Nécessaire pour pouvoir remettre en
# place facilement la réplication suite à un failover/switchover.
archive_mode = on
archive_command = 'rsync %p 192.0.2.2:/srv/pg-archives/%f'

Créer un utilisateur dédié pour la réplication :

postgres=# CREATE ROLE repl WITH LOGIN REPLICATION PASSWORD 'xxxxxxxx';

Autoriser le serveur esclave à se connecter au maître :

hostssl replication     repl             192.0.2.2/32         md5

Configuration du serveur esclave

Cette configuration est relative au serveur esclave, mais elle doit également être reprise à l'identique sur le serveur maître, en renommant le fichier recovery.conf pour qu'il ne soit pas pris en compte.

Décommenter ou ajouter les directives suivantes dans le fichier /etc/postgresql/9.2/main/postgresql.conf :

# Le serveur est en mode esclave en lecture seule
hot_standby = on

Créer un fichier recovery.conf avec les info suivantes :

# echo "standby_mode = 'on'
> primary_conninfo = 'host=192.0.2.1 user=repl password=xxxxxxxx application_name=foo'
> archive_cleanup_command = '/usr/lib/postgresql/9.2/bin/pg_archivecleanup /srv/pg-archives/ %r'
> recovery_target_timeline = 'latest'" >~postgres/9.2/main/recovery.conf

Il est nécessaire que ce fichier appartiennent à l'utilisateur postgres, notamment pour le [#Passerunserveuresclaveenmaître failover] :

# chown postgres:postgres ~postgres/9.2/main/recovery.conf

Synchronisation initiale des données

  • Arrêter PostgreSQL sur l'esclave ;
  • sur le maître, indiquer à PostgreSQL qu'on commence une sauvegarde. Il va notamment faire un checkpoint dans son WAL courant et retourner sa position :
postgres$ psql -c "SELECT pg_start_backup('synchro initiale')"
  • lancer le rsync du datadir vers l'esclave :
# rsync -avz --delete --exclude /pg_xlog/* --exclude /postmaster.* --exclude /recovery.* ~postgres/9.2/main/ 192.0.2.2:~postgres/9.2/main/
  • indiquer à PostgreSQL que le backup est terminé :
postgres$ psql -c "SELECT pg_stop_backup()"
  • redémarrer PostgreSQL sur l'esclave.

Administration

Monitoring

Plusieurs possibilité pour surveiller la réplication :

  • Voir la position courante dans les logs sur le maître et l'esclave (on peut en déduire si ils sont synchro ou pas) :
# pgrep -lf "wal (sender|receiver) process"
6891 postgres: wal receiver process   streaming 0/C085240
  • PostgreSQL fournit la vue pg_stat_replication() qui permet de lister les connexions aux processus walsender, avec différentes informations utiles :
postgres=# SELECT * from pg_stat_replication;
-[ RECORD 1 ]----+------------------------------
pid              | 29745
usesysid         | 16387
usename          | repl
application_name | foo
client_addr      | 192.0.2.2
client_hostname  |
client_port      | 46581
backend_start    | 2013-04-30 10:39:43.230287-04
state            | streaming
sent_location    | 0/C0873B8
write_location   | 0/C0873B8
flush_location   | 0/C0873B8
replay_location  | 0/C0873B8
sync_priority    | 0
sync_state       | async

Les données à surveiller sont notamment les _*location, qui indique la position courante dans les WAL à différentes étapes de la réplication. Voir http://www.postgresql.org/docs/9.2/static/monitoring-stats.html#PG-STAT-REPLICATION-VIEW pour le détails des champs.

  • Pour pouvoir quantifié le retard de réplication, on peut utiliser la commande check_postgres avec l'option hot_standby_delay :
$ check_postgres --action=hot_standby_delay --dbhost=localhost --dbport=5432  --dbname=template1 --dbuser=nrpe --dbpass=xxxxxx --dbhost=192.0.2.2 --dbport=5432 --warning=500000 --critical=1000000
POSTGRES_HOT_STANDBY_DELAY OK: DB "template1" (host:192.0.2.2) 0 | time=0.09s replay_delay=12568;500000;1000000  receive-delay=8192;500000;1000000

Où localhost est le maître et 192.0.2.2 l'esclave. Les valeurs de replay_delay et receive-delay sont à priori exprimées en octets de WAL à rejouer.

Passer un serveur esclave en maître

Si le maître est toujours joignable, éteindre PostgreSQL en forçant la déconnexion des clients :

# pg_ctlcluster 9.2 main stop -- -m fast

Sur l'esclave, faire en sorte que PostgreSQL accepte les connexions en écriture :

# pg_ctlcluster 9.2 main promote

L'esclave va d'abord rattraper son éventuel retard dans le traitement des logs de réplication, puis une fois prêt se mettra à accepter les requêtes en écritures.

Le fichier recovery.conf est renommé en recovery.done pour qu'il ne soit pas lu en cas de redémarrage de PostgreSQL.

Messages de PostgreSQL lors du passage en maître :

2013-04-23 05:54:15 EDT LOG:  received promote request
2013-04-23 05:54:15 EDT LOG:  redo done at 0/6000020
2013-04-23 05:54:15 EDT LOG:  last completed transaction was at log time 2013-04-23 05:54:10.217923-04
2013-04-23 05:54:15 EDT LOG:  selected new timeline ID: 2
2013-04-23 05:54:15 EDT LOG:  archive recovery complete
2013-04-23 05:54:15 EDT LOG:  database system is ready to accept connections
2013-04-23 05:54:15 EDT LOG:  autovacuum launcher started

ATTENTION : à partir du moment où l'esclave cesse de lire les journaux du maître, toutes les écritures qui continuent de se faire sur le maître seront perdues. Il faut donc être certain que le maître soit réellement inaccessible avant de faire la bascule.

Rétablissement de la réplication après un failover

État courant : le serveur esclave accepte les écritures suite à la procédure de failover, et le serveur maître contient des données obsolètes car pas mises à jour.

Il faut alors mettre en place le recovery.conf sur l'ancien master et démarrer PostgreSQL. Il va alors rejouer les WAL pour rattraper le retard accumulé, puis se mettre en mettre en mode streaming replication.

Arrêter la réplication

  • Arrêter/reprendre le "replay" des WAL sur l'esclave :
postgres=# SELECT pg_xlog_replay_pause();
postgres=# SELECT pg_xlog_replay_resume();
  • Arrêter/reprendre le flux des WAL depuis le maître. Il ne semble pas y avoir de solution autre que de couper le flux au niveau réseau. Sur le maître :
# iptables -I INPUT -s 192.0.2.2 -p tcp --dport 5432 -j REJECT
# iptables -D INPUT 1

Diverses notes/spécificités de la réplication

  • Si une requête sur le serveur esclave bloque la réplication (par exemple un SELECT qui bloque un DROP TABLE) pendant un temps trop long, la requête sur l'esclave sera tuée (ici le SELECT). Ce temps est définit par la directive max_standby_streaming_delay sur la configuration de l'esclave.

Ce comportement peut-être désactivé grâce à la directive hot_standby_feedback, qui fait en sorte que l'esclave communique l'état des requêtes au maître, mais cela à un impact sur le maître.