Database

PostgreSQL Replica: Monitoreo de Retraso entre Sedes

PostgreSQL Replica: Monitoreo de Retraso entre Sedes

La gestión de bases de datos críticas en entornos empresariales exige soluciones robustas de alta disponibilidad y recuperación ante desastres. Entre estas, la réplica continua de PostgreSQL entre sedes geográficamente distantes es una práctica fundamental para garantizar la continuidad operativa y minimizar la pérdida de datos. Sin embargo, una réplica asíncrona, aunque ofrece flexibilidad y rendimiento, introduce el riesgo de un retraso (lag) que, si no se monitoriza y gestiona, puede comprometer seriamente el Recovery Point Objective (RPO) en caso de un failover. He visto escenarios donde un RPO de pocos segundos se transformaba en minutos, o incluso horas, debido a un retraso de réplica subestimado, con consecuencias desastrosas para el negocio. Este artículo explora cómo configurar y, sobre todo, monitorizar eficazmente el retraso de réplica de PostgreSQL, basándose en una experiencia real de implementación y gestión en un entorno crítico.

Tested on: PostgreSQL 15 · Ubuntu 22.04 LTS · Septiembre 2026

Requisitos Previos / Entorno de Prueba

Para implementar la réplica continua y su correspondiente monitorización, es necesario disponer de dos servidores PostgreSQL, uno configurado como master (primario) y el otro como standby (réplica), preferiblemente en redes y centros de datos distintos. Asegúrate de que los dos servidores puedan comunicarse a través del puerto de PostgreSQL (típicamente 5432) y que el tráfico sea seguro (por ejemplo, mediante VPN o túnel SSH). Para esta configuración, usaremos dos instancias de PostgreSQL 15 en Ubuntu 22.04 LTS. Es fundamental tener un usuario dedicado a la réplica con privilegios adecuados y que los sistemas de archivos de los servidores tengan espacio suficiente para los Write-Ahead Logs (WAL).

1. Configuración del servidor Master (Primario)

El primer paso es configurar el servidor master para permitir la réplica. Modifica el archivo postgresql.conf (normalmente en /etc/postgresql/15/main/postgresql.conf) con los siguientes parámetros:

wal_level = replica
archive_mode = on
archive_command = 'cp %p /mnt/pg_wal_archive/%f'
max_wal_senders = 10
listen_addresses = '*'
  • wal_level = replica: habilita la escritura de la información necesaria para la réplica en los WAL.
  • archive_mode = on: habilita el archivado de los segmentos WAL completados. archive_command especifica cómo archivar los archivos. En un entorno de producción, se usaría un sistema de almacenamiento remoto (NFS, S3, etc.) o una herramienta como pg_basebackup o barman para el archivado y la recuperación. Para nuestra prueba, usaremos una simple copia local.
  • max_wal_senders = 10: define el número máximo de procesos walsender que pueden iniciarse. Cada standby requiere un walsender.
  • listen_addresses = '*': permite a PostgreSQL aceptar conexiones desde cualquier dirección IP. En producción, es aconsejable especificar direcciones IP específicas o subredes por motivos de seguridad.

Posteriormente, modifica el archivo pg_hba.conf para permitir que la réplica se conecte. Añade una línea similar a esta:

host    replication     all             <IP_STANDBY>/32         md5

Sustituye por la dirección IP de tu servidor standby. Crea un usuario de réplica:

CREATE USER replicator WITH REPLICATION ENCRYPTED PASSWORD 'your_secure_password';

Reinicia el servicio PostgreSQL en el master para aplicar los cambios:

sudo systemctl restart postgresql@15-main

2. Preparación del servidor Standby (Réplica)

Antes de configurar el standby, es necesario crear una base de partida (base backup) desde el master. Esto se puede hacer con pg_basebackup directamente desde el servidor standby:

sudo -u postgres pg_basebackup -h <IP_MASTER> -D /var/lib/postgresql/15/main -U replicator -P -v -R
  • -h : dirección IP del servidor master.
  • -D /var/lib/postgresql/15/main: directorio de los datos de PostgreSQL en el servidor standby.
  • -U replicator: usuario de réplica creado anteriormente.
  • -P: muestra el progreso.
  • -v: salida verbosa.
  • -R: crea automáticamente un archivo standby.signal y añade las configuraciones necesarias a postgresql.auto.conf para iniciar el standby. Esto reemplaza el antiguo recovery.conf en las versiones recientes de PostgreSQL.

Si utilizas una versión más antigua de PostgreSQL que requiere recovery.conf, el comando -R generará un archivo recovery.conf con el siguiente contenido (o similar):

standby_mode = 'on'
primary_conninfo = 'host=<IP_MASTER> port=5432 user=replicator password=your_secure_password application_name=standby1'
primary_slot_name = 'standby_slot'

Asegúrate de que primary_conninfo contenga la dirección IP correcta del master y la contraseña del usuario replicator.

Inicia el servicio PostgreSQL en el standby:

sudo systemctl start postgresql@15-main

Verifica el estado de la réplica en el master con ps aux | grep walsender y en el standby con ps aux | grep walreceiver. Deberías ver los procesos activos. Lee también: Hardening SSH en Linux: Guía Completa 2026

3. Monitorización del retraso de réplica

La monitorización del retraso de réplica es crucial. PostgreSQL proporciona funciones integradas para este propósito. Conéctate a la base de datos en el servidor standby y usa la siguiente consulta:

SELECT pg_last_wal_receive_lsn(), pg_last_wal_replay_lsn(),
       (pg_wal_lsn_diff(pg_last_wal_receive_lsn(), pg_last_wal_replay_lsn())) AS byte_lag,
       (EXTRACT(EPOCH FROM now() - pg_last_xact_replay_timestamp())) AS time_lag_seconds;
  • pg_last_wal_receive_lsn(): el LSN (Log Sequence Number) del último registro WAL recibido por el standby.
  • pg_last_wal_replay_lsn(): el LSN del último registro WAL aplicado (replay) por el standby.
  • byte_lag: la diferencia en bytes entre los WAL recibidos y los aplicados. Un valor mayor indica un retraso en términos de datos.
  • time_lag_seconds: el retraso en segundos basado en el timestamp de la última transacción replicada. Este es a menudo el dato más relevante para el RPO.

Un retraso byte_lag o time_lag_seconds constantemente superior a cero indica que la réplica es asíncrona. Si estos valores aumentan de forma significativa, significa que el standby no logra seguir el ritmo del master.

Es posible crear una tabla y una función para registrar el retraso a lo largo del tiempo, para análisis históricos y para integrar con sistemas de monitorización como Prometheus o Zabbix:

CREATE TABLE replica_lag_history (
    timestamp TIMESTAMPTZ DEFAULT now(),
    byte_lag BIGINT,
    time_lag_seconds INT
);

CREATE OR REPLACE FUNCTION record_replica_lag()
RETURNS VOID AS $$
DECLARE
    current_byte_lag BIGINT;
    current_time_lag_seconds INT;
BEGIN
    SELECT (pg_wal_lsn_diff(pg_last_wal_receive_lsn(), pg_last_wal_replay_lsn())) INTO current_byte_lag;
    SELECT (EXTRACT(EPOCH FROM now() - pg_last_xact_replay_timestamp())) INTO current_time_lag_seconds;

    INSERT INTO replica_lag_history (byte_lag, time_lag_seconds)
    VALUES (current_byte_lag, current_time_lag_seconds);
END;
$$ LANGUAGE plpgsql;

-- Ejecutar cada minuto
SELECT cron.schedule('record_replica_lag', '* * * * *', 'SELECT record_replica_lag();');

Errores Comunes y Resolución de Problemas

  • Conexión rechazada: Comprueba pg_hba.conf en el master y las reglas del firewall. Asegúrate de que el puerto 5432 esté abierto y que el usuario replicator tenga los permisos correctos.
  • Standby no se inicia: Verifica los logs de PostgreSQL en el servidor standby (/var/log/postgresql/postgresql-15-main.log). Errores comunes incluyen primary_conninfo incorrecto, directorio de datos no vacío antes de pg_basebackup, o problemas de permisos.
  • Retraso de réplica elevado: Esto puede ser causado por varios factores: insuficiente I/O en el servidor standby, red lenta entre master y standby, carga excesiva en el master que genera demasiados WAL, o recursos insuficientes en el standby para aplicar los WAL. Comprueba las métricas de I/O, CPU y red en ambos servidores. Un enlace externo útil para profundizar es la documentación oficial de PostgreSQL sobre la Streaming Replication.

FAQ — Preguntas Frecuentes

¿La réplica asíncrona garantiza cero pérdida de datos?

No, la réplica asíncrona no garantiza un RPO cero. Siempre hay un potencial retraso entre el momento en que una transacción se confirma en el master y cuando se aplica en el standby. En caso de un fallo inesperado del master, las transacciones que aún no se hayan replicado en el standby se perderán. Para un RPO cero, es necesaria la réplica síncrona, que sin embargo introduce latencia en las escrituras en el master.

¿Cómo puedo reducir el retraso de réplica?

Para reducir el retraso, asegúrate de que el servidor standby tenga recursos de hardware (CPU, RAM, I/O) adecuados para procesar los WAL. Optimiza la red entre master y standby para reducir la latencia y aumentar el ancho de banda. En el master, evalúa la optimización de las consultas para reducir la cantidad de WAL generados. Si el retraso es persistente e inexplicable, podría ser necesario escalar horizontal o verticalmente.

¿Puedo usar el standby para lecturas?

Sí, una de las ventajas principales de la réplica es la posibilidad de utilizar el servidor standby como servidor de solo lectura (read-only) para equilibrar la carga de las consultas. Esto se conoce como Read Replica. Asegúrate de dirigir las consultas de lectura al servidor standby para aligerar la carga en el master y mejorar el rendimiento general del sistema.

¿Qué sucede si el master falla?

Si el master falla, deberás promover manualmente (o automáticamente con herramientas como pg_auto_failover o Patroni) uno de los standby a nuevo master. El proceso de promoción aplicará todos los WAL recibidos y aún no aplicados, y luego el standby comenzará a aceptar escrituras. Es fundamental tener un proceso de failover bien documentado y probado.

Conclusiones con Puntos Clave Operativos

La réplica continua de PostgreSQL es un pilar de la resiliencia infraestructural para las bases de datos. La implementación de una réplica asíncrona entre dos sedes, como se describe, ofrece un buen equilibrio entre rendimiento y protección de datos. Sin embargo, el valor real de esta configuración emerge solo si el retraso de réplica se monitoriza constantemente. Ignorar este aspecto significa operar con un RPO desconocido, una apuesta demasiado arriesgada para cualquier entorno de producción. Integrar las métricas de retraso con el sistema de monitorización central y configurar alertas automáticas es una acción no negociable para garantizar que tu plan de disaster recovery esté siempre alineado con las expectativas.

Comparte este artículo:

Escrito por

Rosario Giordano

Rosario Giordano es administrador de sistemas y consultor de TI especializado en c iberseguridad y cloud, con más de 20 años de experiencia en la gestión de infraestructuras Linux empresariales. Sus áreas de especialización incluyen el hardening de SSH, plataformas Kubernetes , bases de datos PostgreSQL, virtualización con VMware/Proxmox y el cumplimiento de los marcos de seguridad NIS2 e ISO 27001.