Cómo configurar failover automático entre dos VPS Debian con replicación PostgreSQL y evitar split‑brain
Por Kevin Marcondes · Publicado el · 8 min de lectura
¿Quieres aprender a configurar failover automático entre dos VPS Debian con replicación PostgreSQL y evitar split‑brain? El desafío real es disponer de quórum para promover, healthchecks fiables y un punto de entrada estable (VIP/DNS). Aquí tienes una arquitectura práctica con witness, parámetros críticos de replicación, scripts de healthcheck y un playbook de incidentes para reducir riesgos y tiempo de recuperación.
El problema real: dos VPS, particiones de red y riesgo de split‑brain
Con solo dos nodos, cualquier pérdida de conectividad puede hacer que cada lado crea ser el primario. Sin quórum, se produce split‑brain y corrupción lógica de datos.
Para lograr un failover automático fiable, combina detección de fallos, coordinación con consenso (o testigo) y un mecanismo para cambiar el punto de entrada (VIP/DNS). Sin ello, la automatización se vuelve una ruleta.
- Detección: healthchecks que validen que el primario está operativo y puede escribir.
- Coordinación: witness/DCS para desempatar decisiones de promoción.
- Cambio de tráfico: VIP con Keepalived/VRRP o DNS con TTL bajo.
Arquitectura segura recomendada (2 nodos + witness + VIP)
Usa dos VPS Debian (primario y standby) y un elemento ligero como witness o un servicio de consenso (DCS) — por ejemplo, etcd/Consul cuando lo use una herramienta de HA. El VIP queda en el primario sano y acompaña el failover.
Crea un túnel privado entre las VPS para replicación y checks de salud. Esto reduce la exposición y ayuda con la latencia. Si hace falta, sigue este paso a paso de túnel site‑to‑site con WireGuard: cómo configurar WireGuard site-to-site.
Implementa fencing lógico: si el primario pierde contacto con el witness, debe abdicar del VIP y rechazar escrituras. Este guard‑rail reduce drásticamente el riesgo de split‑brain.
- Primario: recibe escrituras y anuncia el VIP.
- Standby: replica y puede ser promovido automáticamente.
- Witness/DCS: provee quórum en la promoción.
- VIP vía Keepalived/VRRP: punto de entrada estable.
- Canal privado: túnel WireGuard entre las VPS.
Replicación: opciones y parámetros esenciales en PostgreSQL
La replicación nativa por streaming cubre la mayoría de los casos. Elige síncrona (RPO≈0, más latencia) o asíncrona (menos latencia, pequeño riesgo de pérdida en el failover).
Ajusta parámetros para estabilidad y previsibilidad durante failover y reingreso. Cuanto más explícitos sean los límites de WAL y checkpoints, menos sorpresas en incidentes.
Sincroniza credenciales y configuraciones de forma controlada. Usa migrations y un plan de rollback para evitar divergencias entre nodos al cambiar el esquema.
- synchronous_commit y synchronous_standby_names (quórum o 1‑sync).
- wal_keep_size y slots de replicación para evitar caídas.
- primary_conninfo con SSL/TLS en el enlace de replicación.
- hot_standby=on para lecturas en el standby.
- checkpoint_timeout y max_wal_size compatibles con el volumen.
Herramientas de orquestación: compara antes de elegir
Automatizar el failover requiere una orquestación fiable. Evalúa prioridades: simplicidad, funcionalidades, integración con VIP/DNS y curva operativa. La elección depende del equipo y del entorno.
| Opción | Cómo funciona | Ventajas | Precauciones / Limitaciones | Cuándo usar |
|---|---|---|---|---|
| Patroni + etcd/Consul | Plano de control con DCS, promoción y reingreso gestionados | Líder con lock; switchover/failover claros; hooks | Necesita un DCS estable; requiere aprendizaje operativo | Entornos que buscan HA madura y flexible |
| repmgr + witness | Daemon que monitoriza nodos; witness desempata la promoción | Ligero e integrado con PostgreSQL | Planear witness y fencing con cuidado | Instalaciones sencillas con dos nodos + testigo |
| pg_auto_failover | Monitor coordina primario/standby y failover | Fácil de iniciar; foco en HA nativa | Menos flexible en escenarios complejos | Equipos pequeños que priorizan simplicidad |
| Keepalived + scripts | VIP decide activo mediante healthcheck personalizado | Control fino sin DCS externo | Debes crear los guard‑rails anti split‑brain | Entornos mínimos con requisitos bien definidos |
Healthcheck seguro del VIP: anuncia solo con quórum
Un healthcheck frágil facilita el split‑brain. El script siguiente solo devuelve éxito si el nodo es primario y puede comunicarse con el witness/DCS. En Keepalived, úsalo como vrrp_script. Nunca anuncies el VIP sin confirmar quórum.
Ajusta PG_URI, WITNESS_HOST/PORT y la exigencia de síncronos según tu política de RPO y topología.
#!/usr/bin/env bash
set -euo pipefail
PG_URI="${PG_URI:-postgresql://[email protected]/postgres}"
WITNESS_HOST="${WITNESS_HOST:-10.0.0.10}"
WITNESS_PORT="${WITNESS_PORT:-2380}" # etcd (use 8300 p/ Consul)
REQUIRED_SYNC="${REQUIRED_SYNC:-0}"
# 1) É primário e gravável?
if ! psql "$PG_URI" -tAc "SELECT NOT pg_is_in_recovery();" | grep -qx "t"; then
exit 1
fi
# 2) Consegue falar com o witness/DCS? Evita VIP em partição isolada
if ! timeout 1 bash -c ">/dev/tcp/$WITNESS_HOST/$WITNESS_PORT"; then
exit 1
fi
# 3) (Opcional) Garante standby(s) síncrono(s) prontos se exigir RPO≈0
if [ "$REQUIRED_SYNC" -gt 0 ]; then
READY=$(psql "$PG_URI" -tAc "SELECT count(*) FROM pg_stat_replication WHERE sync_state IN ('sync','quorum');")
if [ "$READY" -lt "$REQUIRED_SYNC" ]; then
exit 1
fi
fi
exit 0
Playbook de incidentes: promoción, retorno y reingreso seguro
Define un runbook corto y probado. Al fallar el primario, la orquestación promociona el standby y el VIP cambia. Si hay sospecha de partición, fuerza al antiguo primario a rechazar escrituras y a soltar el VIP. Al volver, haz el reingreso como réplica siguiendo la cronología vencedora.
Mantén backups consistentes para soportar PITR. Consulta enfoques prácticos en backups incrementales y cifrados en S3 y cómo ejecutar un PITR sin downtime.
- Fallo detectado: el VIP cambia y el standby se promociona automáticamente.
- Partición: el antiguo primario sin VIP y sin escrituras hasta confirmar quórum.
- Retorno: reingreso del nodo recuperado como standby en la timeline vencedora.
- Cambios de esquema: hazlos vía migrations con ventana y rollback.
Pruebas de DR: validar failover sin interrumpir el negocio
Prueba en una ventana controlada. Valida el cambio del VIP, la continuidad de escrituras y la consistencia tras switchover y failover simulado. Saca snapshot/backup antes del ejercicio. Audita el estado antes y después y registra lecciones en el runbook.
Refuerza el hardening del host para reducir falsos positivos y fallos colaterales. Consulta el checklist de seguridad para VPS Linux.
- Crea/actualiza una tabla de prueba antes del switchover.
- Provoca switchover/failover con la herramienta elegida.
- Confirma que el antiguo primario pasó a standby y los datos persisten.
# No primário atual
psql -tAc "SELECT pg_is_in_recovery();"
psql -c "CREATE TABLE IF NOT EXISTS ha_test(id int primary key); INSERT INTO ha_test VALUES (1) ON CONFLICT DO NOTHING;"
# Execute o switchover/failover pela orquestração
# No novo primário
psql -tAc "SELECT pg_is_in_recovery(); SELECT count(*) FROM ha_test;"
Checklist anti split‑brain y tiempos de failover
Céntrate en los tiempos y en las condiciones de promoción. El checklist siguiente ayuda a reducir riesgos en dos VPS con witness. Revísalo periódicamente según incidentes y crecimiento de carga. Timeouts cortos provocan failovers indebidos; largos retrasan la recuperación.
- El healthcheck del VIP solo pasa si: es primario real + witness accesible.
- Timeouts coherentes: detección (3–10s), promoción (10–30s), anuncio del VIP (≥ detección).
- Si usas síncrona: garantiza al menos 1 standby listo (quórum).
- Evita reinicios en bucle; usa backoff exponencial en los servicios.
- Monitorea lag de replicación y reaplicación de WALs en el standby.
- Documenta pasos de reingreso y limpieza de timelines antiguas.
Preguntas frecuentes
¿Necesito un tercer nodo para evitar split‑brain?
En escenarios con dos VPS, un tercer elemento (witness o DCS) es la forma más segura de evitar split‑brain. Proporciona quórum para decisiones de promoción. Sin quórum, las particiones de red pueden crear dos primarios simultáneos y corromper datos.
¿Puedo tener RPO≈0 con solo dos VPS?
Sí, usando replicación síncrona con un standby. Reduces el riesgo de pérdida de datos, pero aumentas la latencia de escritura y la sensibilidad a fallos de red. Asegura healthchecks robustos y witness accesible antes de anunciar el VIP; de lo contrario la indisponibilidad puede aumentar.
¿Es mejor Patroni, repmgr o scripts con Keepalived?
Depende de la prioridad. Patroni ofrece automatización madura con DCS. repmgr es más ligero y funciona bien con witness. Keepalived con scripts da control fino, pero debes crear guard‑rails anti split‑brain. Evalúa la experiencia del equipo y la complejidad del entorno.
¿Cómo probar el failover con seguridad?
Haz snapshot/backup, crea una tabla de prueba y fuerza un switchover programado. Verifica el cambio del VIP, el estado de pg_is_in_recovery en ambos nodos y la persistencia de los datos. Monitorea lag y errores en logs. Actualiza el runbook tras el ejercicio.
¿Qué hacer cuando el antiguo primario vuelve después del failover?
No promociones automáticamente. Quita VIP y permisos de escritura, confirma la timeline vencedora y haz reingreso como standby. Las herramientas de HA tienen comandos de rejoin seguros; evita reconfiguraciones manuales sin validar la timeline para no arriesgar divergencia o pérdida de datos.
¿Quieres revisar tu failover PostgreSQL y playbooks?
Cuéntanos tu escenario con dos VPS Debian. Evaluamos riesgos de split‑brain, reforzamos healthchecks/VIP y organizamos pruebas de DR con replicación consistente.
Hablar sobre failover seguroVer también
- 502 Bad Gateway intermitente en Docker Compose con Nginx y PHP‑FPM: cómo diagnosticar y corregir timeouts y exceso de conexiones
- Cómo diagnosticar y capturar paquetes por intermitencias de red entre contenedores Docker en Debian
- Cómo detectar y corregir inconsistencias de SKUs duplicados entre WooCommerce y ERP sin perder pedidos
- Cómo resolver el error 'Too many open files' en Linux en servidores PHP‑FPM durante picos de carga