Streaming replication de PostgreSQL + failover automático
Síntoma
Objetivo: configurar un hot standby para PostgreSQL con streaming replication y agregar Patroni/repmgr para el failover automático.
1. Configure los parámetros de WAL y de conexión en el primario
Para streaming replication, wal_level debe ser al menos 'replica'. max_wal_senders debe cubrir el número de réplicas + conexiones de backup, y la eliminación prematura de WAL debe evitarse con wal_keep_size o un replication slot. Los cambios requieren reinicio.
PostgreSQL
ALTER SYSTEM SET wal_level = 'replica';
ALTER SYSTEM SET max_wal_senders = 10;
ALTER SYSTEM SET max_replication_slots = 10;
ALTER SYSTEM SET hot_standby = on;
-- To apply the postgresql.conf change:
-- systemctl restart postgresql2. Defina el rol de replicación y el acceso en pg_hba
Cree un rol con el atributo REPLICATION para que el standby se conecte. Agregue a pg_hba.conf una línea que permita el acceso a la base de datos 'replication' desde la IP del standby y recargue con pg_reload_conf().
PostgreSQL
CREATE ROLE replicator WITH REPLICATION LOGIN PASSWORD 'secret';
-- Add to pg_hba.conf:
-- host replication replicator 10.0.0.20/32 scram-sha-256
SELECT pg_reload_conf();3. Cree un replication slot persistente en el primario
Un physical replication slot impide que el primario elimine el WAL necesario aunque el standby se quede atrás; gestionar slots es más seguro que wal_keep_size. Usaremos el nombre del slot en la configuración del standby.
PostgreSQL
SELECT pg_create_physical_replication_slot('standby1_slot');
SELECT slot_name, active, restart_lsn FROM pg_replication_slots;4. Tome un base backup en el servidor standby con pg_basebackup
Con el directorio de datos del standby vacío, tome una copia completa del primario. El flag -R escribe automáticamente el archivo standby.signal y primary_conninfo; -C también puede crear el slot. El nombre del slot se pasa con -S.
PostgreSQL
pg_basebackup -h 10.0.0.10 -U replicator -D /var/lib/pgsql/data \
-R -X stream -S standby1_slot -P -v5. Verifique primary_conninfo y hot_standby, inicie el standby
Compruebe primary_conninfo (host, user, slot) en el postgresql.auto.conf escrito por -R; la presencia del archivo standby.signal determina el modo standby. Con hot_standby=on el standby acepta consultas de solo lectura. Inicie el servicio.
PostgreSQL
-- Expected in postgresql.auto.conf:
-- primary_conninfo = 'host=10.0.0.10 user=replicator password=secret'
-- primary_slot_name = 'standby1_slot'
-- systemctl start postgresql
SELECT pg_is_in_recovery(); -- should return true on the standby6. Monitoree el lag de replicación desde el primario
En el primario, pg_stat_replication muestra el LSN enviado/reproducido y el lag de cada standby. El lag de write/flush/replay debe mantenerse bajo; sync_state es 'sync' si se usa una réplica síncrona.
PostgreSQL
SELECT client_addr, state, sync_state,
pg_wal_lsn_diff(sent_lsn, replay_lsn) AS replay_lag_bytes,
write_lag, flush_lag, replay_lag
FROM pg_stat_replication;7. Agregue Patroni o repmgr para el failover automático
La streaming replication por sí sola requiere un promote manual. El failover automático requiere un gestor de clúster: Patroni (elección de líder sobre etcd/Consul + promote automático) o repmgr (monitoreo/failover con repmgrd). En el lado de la aplicación, ofrezca un único endpoint con HAProxy/pgBouncer. Si se necesita un promote manual: pg_ctl promote. Antes de promover, asegúrese de que el primario antiguo esté realmente detenido y de que las aplicaciones no puedan escribir en él (riesgo de split-brain). Reincorporar el primario antiguo como standby del nuevo primario requiere pg_rewind; para ello, wal_log_hints = on o los data checksums deben estar habilitados.
PostgreSQL
-- Manual promote (if there is no cluster manager):
pg_ctl promote -D /var/lib/pgsql/data
-- or via SQL:
SELECT pg_promote();
-- With Patroni: patronictl -c /etc/patroni.yml switchover mycluster