PostgreSQL n'inclut pas de basculement automatique prêt à l'emploi.
Lorsque le serveur principal tombe en panne, quelqu'un doit promouvoir manuellement le serveur de secours, ce qui entraîne une interruption de service.
repmgr ajoute un démon de basculement automatique (repmgrd) qui surveille le cluster et promeut le standby en quelques secondes lorsque le primaire échoue.
Ce guide explique comment configurer un cluster PostgreSQL 18 à deux nœuds avec réplication en streaming et basculement automatique sur Ubuntu 24.04, en utilisant repmgr 5.x.
Chaque étape a été exécutée en direct sur un cluster réel et la sortie a été vérifiée.
Une veille de diffusion en continu qui nécessite une promotion manuelle n'est pas une configuration de haute disponibilité – c'est une configuration de reprise après sinistre.
La différence compte lors d'un incident à 3 heures du matin.
PostgreSQL est livré avec les éléments constitutifs de la réplication, mais la logique de basculement automatique réside dans un outil séparé.
repmgr est l'outil auquel la plupart des DBA PostgreSQL se réfèrent en premier : il est léger, bien documenté et s'intègre proprement avec systemd.
Ce guide construit la pile complète : réplication de flux à partir de zéro, repmgrd fonctionnant en tant que démon, et un basculement automatique testé qui récupère le cluster sans intervention humaine.
Table des matières
L'environnement
Ce guide utilise deux serveurs Ubuntu 24.04 sur le même sous-réseau.
| Hôte | CI | Rôle initial |
|---|---|---|
| serveur1 | 192.168.0.181 | Primaire |
| serveur2 | 192.168.0.182 | Attendez |
PostgreSQL 18 et repmgr 5.5.0 sont installés à partir du dépôt PGDG sur les deux serveurs.
Étape 1 — Installer PostgreSQL 18 et repmgr
PostgreSQL 18 n'est pas dans le dépôt par défaut d'Ubuntu 24.04.
Le postgresql-common le paquet comprend un script officiel qui ajoute automatiquement le dépôt APT PGDG et la clé de signature.
Sur les deux serveurs :
sudo apt install -y postgresql-common
sudo /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh
sudo apt update
sudo apt install -y postgresql-18 postgresql-18-repmgr
Vérifier l'installation :
psql --version
# Expected: psql (PostgreSQL) 18.x
repmgr --version
# Expected: repmgr 5.x
Sur server2, arrêtez PostgreSQL et supprimez le répertoire de données par défaut.
repmgr clonera le répertoire de données du primaire vers server2 dans une étape ultérieure – si un répertoire de données existe déjà, repmgr standby clone refusera de continuer.
# On server2
sudo systemctl stop postgresql
sudo rm -rf /var/lib/postgresql/18/main
Étape 2 — Configurer PostgreSQL pour la réplication en flux
Ces paramètres doivent être définis dans /etc/postgresql/18/main/postgresql.conf sur les deux serveurs avant de configurer la réplication.
repmgr nécessite wal_log_hints et bibliothèques_prechargées_partagées — sans eux, le processus de rejoin de nœud (pg_rewind) et le démon repmgrd ne fonctionneront pas.
Sur les deux serveurs, modifiez /etc/postgresql/18/main/postgresql.conf:
Ces paramètres nécessitent un redémarrage de PostgreSQL pour prendre effet.
Ne redémarrez pas encore — ajoutez le pg_hba.conf entrées d'abord afin de ne pas redémarrer deux fois.
Étape 3 — Autoriser les connexions de réplication dans pg_hba.conf
Sur les deux serveurs, ajoutez ces lignes à /etc/postgresql/18/main/pg_hba.conf.
Ceux-ci permettent la repmgr utilisateur pour se connecter aux requêtes de gestion et au streaming WAL depuis l'un ou l'autre nœud.
sudo tee -a /etc/postgresql/18/main/pg_hba.conf > /dev/null << 'EOF'
host repmgr repmgr 192.168.0.181/32 scram-sha-256
host repmgr repmgr 192.168.0.182/32 scram-sha-256
host replication repmgr 192.168.0.181/32 scram-sha-256
host replication repmgr 192.168.0.182/32 scram-sha-256
EOF
Redémarrez maintenant PostgreSQL sur server1 (server2 n'a pas encore de répertoire de données) :
# On server1
sudo systemctl restart postgresql
Étape 4 — Créer l'utilisateur et la base de données repmgr
Exécutez ces commandes sur server1 (le primaire) uniquement.
La sauvegarde recevra le schéma repmgr par réplication dans une étape ultérieure.
sudo -u postgres psql -c "CREATE USER repmgr WITH SUPERUSER REPLICATION LOGIN PASSWORD 'repmgr';"
sudo -u postgres psql -c "CREATE DATABASE repmgr OWNER repmgr;"
Ajouter un .pgpass fichier pour l'utilisateur postgres de l'OS sur les deux serveurs afin que repmgr puisse se connecter sans invite de mot de passe.
Sur le serveur1 :
sudo -u postgres bash -c 'cat > /var/lib/postgresql/.pgpass <<EOF
192.168.0.181:5432:repmgr:repmgr:repmgr
192.168.0.182:5432:repmgr:repmgr:repmgr
192.168.0.181:5432:replication:repmgr:repmgr
192.168.0.182:5432:replication:repmgr:repmgr
EOF'
sudo chmod 600 /var/lib/postgresql/.pgpass
Sur le serveur2 :
sudo -u postgres bash -c 'cat > /var/lib/postgresql/.pgpass <<EOF
192.168.0.181:5432:repmgr:repmgr:repmgr
192.168.0.182:5432:repmgr:repmgr:repmgr
192.168.0.181:5432:replication:repmgr:repmgr
192.168.0.182:5432:replication:repmgr:repmgr
EOF'
sudo chmod 600 /var/lib/postgresql/.pgpass
Étape 5 — Configurer repmgr sur les deux nœuds
Créer /etc/repmgr.conf sur chaque serveur.
Le pg_bindir paramètre est requis sur Ubuntu — le pg_rewind le binaire n'est pas dans le PATH par défaut pour l'utilisateur OS postgres, et repmgr en a besoin lors de la réintégration du nœud après un basculement.
Le commande_démarrage_service et commande_arrêt_service paramètres sont requis : sans commande_arrêt_service, les basculements planifiés échouent avec “ impossible de confirmer l'arrêt du primaire ” ; sans commande_démarrage_service, un nœud ne peut pas rejoindre le cluster automatiquement après avoir été réinitialisé.
Sur le serveur1 :
sudo tee /etc/repmgr.conf > /dev/null << 'EOF'
node_id=1
node_name='server1'
conninfo='host=192.168.0.181 user=repmgr dbname=repmgr connect_timeout=2'
data_directory='/var/lib/postgresql/18/main'
failover=automatic
promote_command='repmgr standby promote -f /etc/repmgr.conf --log-to-file'
follow_command='repmgr standby follow -f /etc/repmgr.conf --upstream-node-id=%n --log-to-file'
use_replication_slots=yes
monitoring_history=yes
log_file='/var/log/repmgr/repmgr.log'
pg_bindir='/usr/lib/postgresql/18/bin'
service_start_command='sudo systemctl start postgresql'
service_stop_command='sudo systemctl stop postgresql'
node_rejoin_timeout=120
standby_reconnect_timeout=120
EOF
sudo chown postgres:postgres /etc/repmgr.conf
sudo chmod 640 /etc/repmgr.conf
Sur le serveur2, uniquement id_noeud et nom_du_nœud différent :
sudo tee /etc/repmgr.conf > /dev/null << 'EOF'
node_id=2
node_name='server2'
conninfo='host=192.168.0.182 user=repmgr dbname=repmgr connect_timeout=2'
data_directory='/var/lib/postgresql/18/main'
failover=automatic
promote_command='repmgr standby promote -f /etc/repmgr.conf --log-to-file'
follow_command='repmgr standby follow -f /etc/repmgr.conf --upstream-node-id=%n --log-to-file'
use_replication_slots=yes
monitoring_history=yes
log_file='/var/log/repmgr/repmgr.log'
pg_bindir='/usr/lib/postgresql/18/bin'
service_start_command='sudo systemctl start postgresql'
service_stop_command='sudo systemctl stop postgresql'
node_rejoin_timeout=120
standby_reconnect_timeout=120
EOF
sudo chown postgres:postgres /etc/repmgr.conf
sudo chmod 640 /etc/repmgr.conf
Créez le répertoire de journaux sur les deux serveurs :
sudo mkdir -p /var/log/repmgr
sudo chown postgres:postgres /var/log/repmgr
Étape 6 — Configuration des clés SSH et du sudo sans mot de passe
Les basculements planifiés nécessitent que repmgr se connecte par SSH d'un nœud à l'autre en tant qu'utilisateur postgres du système d'exploitation et exécute systemctl stop postgresql.
Cette étape est obligatoire — sans elle, les basculements échouent au moment où repmgr tente d'arrêter le primaire actuel à distance.
Configuration de la clé SSH :
Sur le serveur1 — générer une clé et afficher la clé publique :
# On server1
sudo -u postgres ssh-keygen -t ed25519 -N '' -f /var/lib/postgresql/.ssh/id_ed25519
sudo -u postgres cat /var/lib/postgresql/.ssh/id_ed25519.pub
Sur server2 — autoriser la clé publique de server1 :
# On server2
sudo -u postgres mkdir -p /var/lib/postgresql/.ssh
# Paste the public key from server1 in place of <server1-public-key>
sudo -u postgres bash -c 'echo "<server1-public-key>" >> /var/lib/postgresql/.ssh/authorized_keys'
sudo chmod 700 /var/lib/postgresql/.ssh
sudo chmod 600 /var/lib/postgresql/.ssh/authorized_keys
sudo chown -R postgres:postgres /var/lib/postgresql/.ssh
Répétez dans l'autre sens — sur server2, générez une clé, puis autorisez-la sur server1 :
# On server2
sudo -u postgres ssh-keygen -t ed25519 -N '' -f /var/lib/postgresql/.ssh/id_ed25519
sudo -u postgres cat /var/lib/postgresql/.ssh/id_ed25519.pub
# On server1
sudo -u postgres mkdir -p /var/lib/postgresql/.ssh
sudo -u postgres bash -c 'echo "<server2-public-key>" >> /var/lib/postgresql/.ssh/authorized_keys'
sudo chmod 700 /var/lib/postgresql/.ssh
sudo chmod 600 /var/lib/postgresql/.ssh/authorized_keys
sudo chown -R postgres:postgres /var/lib/postgresql/.ssh
Vérifier à partir de chaque nœud (type oui si on vous demande d'accepter la clé hôte (uniquement la première fois) :
# On server1
sudo -u postgres ssh postgres@192.168.0.182 "echo OK"
# Expected: OK
# On server2
sudo -u postgres ssh postgres@192.168.0.181 "echo OK"
# Expected: OK
Sudo sans mot de passe — sur les deux serveurs :
Créer /etc/sudoers.d/postgres-repmgr pour permettre à l'utilisateur postgres de démarrer et d'arrêter PostgreSQL sans mot de passe.
Le chemin doit être /usr/bin/systemctl — sur Ubuntu 24.04, c'est là que se trouve systemctl, et sudo valide le chemin exact.
Le fichier doit avoir les permissions 440 — sudo ignore silencieusement les fichiers ayant des permissions lisibles par tout le monde.
sudo tee /etc/sudoers.d/postgres-repmgr > /dev/null << 'EOF'
postgres ALL=(ALL) NOPASSWD: /usr/bin/systemctl start postgresql, /usr/bin/systemctl stop postgresql, /usr/bin/systemctl restart postgresql
EOF
sudo chmod 440 /etc/sudoers.d/postgres-repmgr
Vérifier — aucune invite de mot de passe attendue :
sudo -u postgres sudo systemctl status postgresql@18-main
Étape 7 — Enregistrer le primaire et cloner le secondaire
Sur server1, enregistrez l'instance PostgreSQL en cours d'exécution comme nœud principal :
# On server1
sudo -u postgres repmgr -f /etc/repmgr.conf primary register
Sur le serveur2, exécutez d'abord une simulation pour confirmer la connectivité :
# On server2
sudo -u postgres repmgr -h 192.168.0.181 -U repmgr -d repmgr \
-f /etc/repmgr.conf standby clone --dry-run
# Expected: "STANDBY CLONE (target node \"server2\") would complete successfully"
Ensuite, lancez le clonage réel :
# On server2
sudo -u postgres repmgr -h 192.168.0.181 -U repmgr -d repmgr \
-f /etc/repmgr.conf standby clone
Sur Ubuntu, postgresql.conf et pg_hba.conf vivre dans /etc/postgresql/18/main/ — en dehors du répertoire de données.pg_basebackup ne copie que le répertoire des données, donc ces fichiers de configuration ne sont pas copiés automatiquement.
Copiez-les du serveur1 au serveur2 :
# On server1 — stage the files for transfer
sudo cp /etc/postgresql/18/main/postgresql.conf /tmp/postgresql.conf
sudo cp /etc/postgresql/18/main/pg_hba.conf /tmp/pg_hba.conf
sudo chmod 644 /tmp/postgresql.conf /tmp/pg_hba.conf
# On server2 — copy and install
scp fernando@192.168.0.181:/tmp/postgresql.conf /tmp/postgresql.conf
scp fernando@192.168.0.181:/tmp/pg_hba.conf /tmp/pg_hba.conf
sudo cp /tmp/postgresql.conf /etc/postgresql/18/main/postgresql.conf
sudo cp /tmp/pg_hba.conf /etc/postgresql/18/main/pg_hba.conf
Démarrer PostgreSQL sur le serveur2 et l'enregistrer en tant que réplique :
# On server2
sudo systemctl start postgresql
sudo -u postgres repmgr -f /etc/repmgr.conf standby register
Vérifier le cluster depuis l'un ou l'autre nœud :
sudo -u postgres repmgr -f /etc/repmgr.conf cluster show
Résultat attendu :
ID | Name | Role | Status | Upstream | Location | Priority | Timeline | Connection string
----+---------+---------+-----------+----------+----------+----------+----------+----------------------------------------------------------
1 | server1 | primary | * running | | default | 100 | 1 | host=192.168.0.181 user=repmgr dbname=repmgr connect_timeout=2
2 | server2 | standby | running | server1 | default | 100 | 1 | host=192.168.0.182 user=repmgr dbname=repmgr connect_timeout=2
Étape 8 — Démarrer repmgrd pour le basculement automatique
repmgrd est le démon de surveillance qui déclenche le basculement automatique.
Sur Ubuntu 24.04, repmgr n'inclut pas de fichier d'unité systemd pour repmgrd — démarrez-le manuellement en utilisant --daemoniser.
Sur les deux serveurs :
sudo -u postgres repmgrd -f /etc/repmgr.conf --daemonize
Vérifiez que le démon est en cours d'exécution et non en pause :
sudo -u postgres repmgr daemon status
Résultat attendu :
ID | Name | Role | Status | repmgrd Active | PID | Paused? | Upstream
----+---------+---------+-----------+----------------+------+---------+---------
1 | server1 | primary | * running | yes | XXXX | no | n/a
2 | server2 | standby | running | yes | XXXX | no | server1
Le Mis en pause ? non la colonne est critique — repmgrd s'interrompt lui-même après une tentative de basculement échouée et ne tentera pas un nouveau basculement tant qu'il sera en pause.
Avant tout test de basculement, vérifiez que les deux nœuds affichent Mis en pause ? non.
Si un nœud présente En pause ? oui, exécuter :
sudo -u postgres repmgr daemon unpause
Étape 9 — Tester le basculement automatique
Arrêter PostgreSQL sur server1 pour simuler une défaillance du primaire :
# On server1
sudo systemctl stop postgresql
Sur server2, observez la réaction de repmgrd :
# On server2
sudo tail -f -n 50 /var/log/repmgr/repmgr.log
repmgrd attend un nombre configurable de tentatives de reconnexion (par défaut : 6 tentatives × 10 secondes = ~60 secondes) avant de promouvoir la réplique.
Lorsque la promotion est terminée, le journal indique :
NOTICE: promoting standby to primary
NOTICE: STANDBY PROMOTE successful
Vérifier la nouvelle topologie :
# On server2
sudo -u postgres repmgr -f /etc/repmgr.conf cluster show
server2 est maintenant principal, server1 est indiqué comme indisponible.
Étape 10 — Rejoindre le nœud défaillant en tant que secondaire
Après le basculement, server1 doit être réintégré.
PostgreSQL a peut-être progressé sur server2 pendant que server1 était en panne — les répertoires de données ont maintenant divergé.
repmgr utilise pg_rewind pour synchroniser server1 sur la chronologie du nouveau primaire avant de démarrer la réplication.
Sur server1, vérifiez que PostgreSQL est arrêté, puis exécutez :
# On server1
sudo systemctl status postgresql@18-main
# Expected: inactive (dead) — if active, stop it first: sudo systemctl stop postgresql
sudo -u postgres repmgr node rejoin \
-d 'host=192.168.0.182 user=repmgr dbname=repmgr' \
-f /etc/repmgr.conf \
--force-rewind \
--verbose
--rembobinage-forcé demande à repmgr de s'exécuter pg_rewind quelle que soit la divergence de chronologie vérifiée.
Sur Ubuntu 24.04, la reconnexion expire parfois avant que PostgreSQL ne termine le démarrage en tant que réplique.
Si la commande se termine avec un message de délai d'attente mais que le journal indique que pg_rewind s'est terminé avec succès, démarrez PostgreSQL manuellement :
sudo systemctl start postgresql
Enregistrer le serveur server1 dans les métadonnées de repmgr et démarrer le démon repmgrd.
Le --forcer le drapeau est requis car server1 était précédemment enregistré comme principal :
sudo -u postgres repmgr -f /etc/repmgr.conf standby register --force
sudo -u postgres repmgrd -f /etc/repmgr.conf --daemonize
Vérifier que les deux nœuds fonctionnent :
sudo -u postgres repmgr -f /etc/repmgr.conf cluster show
Attendu : server1 listé comme secondaire, server2 comme principal.
Foire aux questions
repmgr est-il compatible avec PostgreSQL 18 ?
Oui.
repmgr 5.5.0 prend en charge PostgreSQL 18.
Installer depuis le dépôt PGDG en utilisant le paquet postgresql-18-repmgr.
Pourquoi mon basculement planifié échoue-t-il avec le message “ impossible de confirmer l'arrêt du primaire ” ?
Le paramètre service_stop_command n'est pas défini dans /etc/repmgr.conf.
repmgr doit arrêter le primaire actuel via SSH lors d'un basculement et nécessite une commande explicite pour ce faire.
Ajoutez service_stop_command='sudo systemctl stop postgresql' à /etc/repmgr.conf sur les deux nœuds.
Pourquoi repmgrd ne déclenche-t-il pas le basculement même si le primaire est hors ligne ?
repmgrd est en pause.
Le démon s'arrête lui-même après une tentative de basculement échouée pour éviter la promotion en cascade dans les scénarios de split-brain.
Exécutez `repmgr daemon status` pour vérifier la colonne `Paused?` et `repmgr daemon unpause` pour reprendre la surveillance.
Le nœud rétrogradé redémarre-t-il automatiquement après un basculement ?
Non.
repmgr arrête l'ancien primaire lors du basculement mais ne le redémarre pas.
La documentation officielle de repmgr stipule : Le primaire d'origine sera arrêté dans tous les cas, et devra être réintégré manuellement dans le cluster de réplication.
Une fois la bascule terminée, exécutez sudo systemctl start postgresql sur le nœud rétrogradé pour le rétablir en tant que réplique.
Qu'est-ce que pg_rewind et pourquoi est-il nécessaire pour la rejointe d'un nœud ?
pg_rewind resynchronise un répertoire de données PostgreSQL qui a divergé de la ligne temporelle principale.
Cela se produit après un basculement — l'ancien nœud primaire peut avoir validé des transactions qui n'ont pas été répliquées avant sa défaillance.
pg_rewind remplace ces blocs divergés par les données correctes du nouveau primaire, permettant au nœud de reprendre la réplication sans une sauvegarde de base complète.
wal_log_hints = on doit être défini dans postgresql.conf pour que pg_rewind fonctionne.
En résumé
La réplication en flux de PostgreSQL est intégrée ; le basculement automatique nécessite repmgr.
La configuration comprend six parties mobiles qui doivent toutes être correctes : la configuration de PostgreSQL, la configuration de repmgr, les clés SSH entre les utilisateurs postgres, le sudo sans mot de passe pour la gestion des services, les slots de réplication, et repmgrd en cours d'exécution et non mis en pause.
Les points de défaillance les plus courants sont les permissions du fichier sudoers (doivent être 440, pas 644) et le fichier manquant commande_arrêt_service pour les basculements.
Une fois le cluster opérationnel, la prochaine étape consiste à ajouter une adresse IP virtuelle flottante avec Keepalived afin que les applications se connectent toujours automatiquement au nœud principal actuel — voir PostgreSQL repmgr avec Keepalived Ajout d'une VIP flottante.
Si vous construisez un cluster PostgreSQL haute disponibilité pour un environnement de production et que vous souhaitez un deuxième avis sur l'architecture avant de vous engager, prendre contact →
