Dominando la Replicación de PostgreSQL: Tipos y Configuración Explicados

Aprende cómo funcionan la replicación en streaming y lógica de PostgreSQL, cuándo usar cada una y qué verificar antes de una conmutación por error en producción.

Dominando la Replicación de PostgreSQL: Tipos y Configuración Explicados

La replicación de PostgreSQL mantiene un segundo servidor lo suficientemente cerca del primario para que puedas sobrevivir a fallos de hardware, redirigir tráfico de lectura o realizar una migración controlada. Si tu base de datos es una dependencia de producción, necesitas saber qué modelo de replicación de PostgreSQL se adapta a tu tolerancia al riesgo antes de que un nodo falle.

PostgreSQL te ofrece dos opciones comunes: replicación en streaming y replicación lógica. La replicación en streaming copia el WAL a nivel del clúster físico. La replicación lógica envía cambios a nivel de fila desde tablas seleccionadas a través de publicaciones y suscripciones.

Por Qué es Importante la Replicación de PostgreSQL

La replicación ayuda con cuatro problemas operativos cotidianos:

  • Alta disponibilidad: Si el primario falla, puedes promover un standby y apuntar las aplicaciones hacia él.
  • Recuperación ante desastres: Un standby en otra ubicación puede protegerte de una caída a nivel de sitio.
  • Escalado de lectura: Las consultas de solo lectura pueden ejecutarse contra standbys activos en lugar del primario de escritura.
  • Soporte para migraciones: La replicación lógica puede ayudar a mover tablas seleccionadas entre versiones de PostgreSQL o diseños de base de datos.

La replicación no es un reemplazo de las copias de seguridad. Un error, una mala migración o un DELETE accidental pueden replicarse rápidamente. Mantén copias de seguridad probadas y recuperación a un punto en el tiempo junto con la replicación.

Replicación en Streaming (Replicación Física)

La replicación en streaming es la forma más común y fundamental de replicación en PostgreSQL. Funciona enviando registros del Write-Ahead Log (WAL) desde el servidor primario a una o más réplicas. Estos registros WAL representan cada cambio realizado en la base de datos. Las réplicas luego aplican estos registros WAL a sus propios archivos de datos, asegurando que se mantengan consistentes con el primario.

Streaming Síncrono vs. Asíncrono

La replicación síncrona hace que el primario espere a uno o más standbys síncronos antes de informar una confirmación al cliente. El nivel exacto de seguridad depende de synchronous_commit; por ejemplo, esperar a que el WAL se escriba es diferente de esperar a que se reproduzca. Obtienes una protección más fuerte contra la pérdida de confirmaciones reconocidas, pero cada confirmación ahora depende de la latencia de la réplica y la red.

La replicación asíncrona permite que el primario confirme localmente y envíe el WAL a las réplicas después. Es más rápida para escrituras, pero una caída del primario puede perder transacciones recientes que aún no habían llegado a un standby.

Configuración de la Replicación en Streaming (Ejemplo Asíncrono)

Configurar la replicación en streaming implica configurar tanto el servidor primario como la réplica. Aquí tienes una guía simplificada:

1. Configurar el Servidor Primario (postgresql.conf y pg_hba.conf)

En el servidor primario, necesitas habilitar el archivado WAL y las conexiones de replicación.

  • Modificaciones en postgresql.conf:

    wal_level = replica  # o logical para replicación lógica
    max_wal_senders = 5  # Número de conexiones de replicación concurrentes
    wal_keep_size = 512MB # O wal_keep_segments para versiones anteriores
    # Para replicación síncrona, añade:
    # synchronous_standby_names = 'replica1,replica2'
    # O para nombre/prioridad de servidor específico:
    # synchronous_standby_names = '1 (replica1), 2 (replica2)'
    archive_mode = on
    archive_command = 'test ! -f /path/to/wal_archive/%f && cp %p /path/to/wal_archive/%f'
    
    • wal_level: Debe ser al menos replica para replicación en streaming.
    • max_wal_senders: Especifica cuántos servidores standby pueden conectarse simultáneamente.
    • wal_keep_size: Evita que los archivos WAL se eliminen antes de que las réplicas puedan obtenerlos (una alternativa más simple a archive_command para configuraciones básicas, pero el archivado se recomienda para robustez).
    • archive_mode y archive_command: Útiles para la recuperación a un punto en el tiempo (PITR) y para réplicas que necesitan WAL antiguo después de quedarse atrás. En producción, usa un destino de archivo real o una herramienta de copia de seguridad en lugar de un comando de copia local.
  • Modificaciones en pg_hba.conf:

    Permite que la réplica se conecte para replicación. Reemplaza replica_ip_address con la IP real de tu réplica.

    # TYPE  DATABASE        USER            ADDRESS                 METHOD
    host    replication     replication_user  replica_ip_address/32   md5
    

    También necesitarás crear un usuario de replicación:

    -- En el servidor primario:
    CREATE ROLE replication_user WITH REPLICATION LOGIN PASSWORD 'your_password';
    

    Después de modificar estos archivos, recarga la configuración de PostgreSQL:

    pg_ctl reload
    # O reinicia PostgreSQL si es necesario
    

2. Preparar el Servidor Réplica

Antes de iniciar la réplica, debe tener un directorio de datos que sea una copia del directorio de datos del primario en un punto específico en el tiempo. La forma más fácil es usar pg_basebackup.

  • Detén PostgreSQL en la réplica (si está en ejecución).

  • Realiza una copia de seguridad base:

    # Asegúrate de que PGDATA esté vacío o eliminado primero
    pg_basebackup -h primary_host_ip -p 5432 -U replication_user -D /var/lib/postgresql/data/ -Fp -Xs -P -R
    
    • -h, -p, -U: Especifica los detalles de conexión del servidor primario.
    • -D: El directorio de datos para la réplica.
    • -Fp: El formato es plano.
    • -Xs: Transmite WAL durante la copia de seguridad.
    • -P: Muestra el progreso.
    • -R: Escribe la configuración de conexión del standby y crea standby.signal para PostgreSQL 12 y versiones posteriores.
    • Se te pedirá la contraseña del replication_user.

3. Configurar el Servidor Réplica

  • Modificaciones en postgresql.conf (para PG12+):

    hot_standby = on # Permite consultas de solo lectura en la réplica
    primary_conninfo = 'host=primary_host_ip port=5432 user=replication_user password=your_password'
    
    • hot_standby: Habilita consultas de solo lectura en el standby.
    • primary_conninfo: Cadena de conexión al servidor primario.
  • Versiones anteriores de PostgreSQL:

    PostgreSQL 12 eliminó recovery.conf. Si mantienes un servidor más antiguo, crea recovery.conf en el directorio de datos de la réplica:

    standby_mode = 'on'
    primary_conninfo = 'host=primary_host_ip port=5432 user=replication_user password=your_password'
    # Si usas recuperación de archivo en lugar de streaming, especificarías restore_command
    # restore_command = 'cp /path/to/wal_archive/%f %p'
    # recovery_target_timeline = 'latest'
    

    En PostgreSQL 12 y versiones posteriores, el modo standby se controla mediante standby.signal, y primary_conninfo generalmente reside en postgresql.auto.conf cuando se crea con pg_basebackup -R.

4. Iniciar el Servidor Réplica

Inicia el servicio de PostgreSQL en la réplica. Se conectará al primario, recibirá registros WAL y comenzará a sincronizarse. Puedes verificar los registros para confirmación.

Consejo: Para una alta disponibilidad robusta, considera usar herramientas como Patroni o repmgr, que automatizan la conmutación por error y la gestión.

Replicación Lógica

La replicación lógica es una forma más flexible y granular de replicación introducida en PostgreSQL 10. En lugar de replicar bloques completos de datos o registros WAL, replica los cambios de datos basándose en su significado lógico (por ejemplo, sentencias INSERT, UPDATE, DELETE) a nivel de fila. Esto se logra decodificando los registros WAL en un flujo de cambios lógicos.

Características Clave y Casos de Uso:

  • Replicación selectiva: Puedes elegir qué tablas replicar. Las versiones recientes de PostgreSQL también admiten listas de columnas en publicaciones, pero verifica la versión de tu servidor antes de confiar en esa característica.
  • Replicación entre versiones: La replicación lógica puede replicar datos entre diferentes versiones principales de PostgreSQL.
  • Control de esquema: La replicación lógica no replica automáticamente DDL. Crea tablas coincidentes y aplica migraciones de esquema en el suscriptor.
  • Transformación de datos: Aunque no está integrada, la replicación lógica proporciona una base para procesos ETL (Extraer, Transformar, Cargar) más complejos.
  • Replicación desde un primario a una réplica que no es un clon completo: La base de datos de destino no necesita ser una copia física completa de la fuente.

Cómo Funciona:

  1. Publicador: La base de datos fuente (primaria) donde ocurren los cambios de datos. Necesita wal_level = logical. Los cambios se decodifican del WAL en un flujo lógico.
  2. Publicación: Un conjunto nombrado de tablas en el publicador cuyos cambios se replicarán.
  3. Suscriptor: La base de datos de destino (réplica) que recibe los cambios.
  4. Suscripción: Una conexión en el suscriptor que se conecta al publicador y aplica los cambios de una publicación específica.

Configuración de la Replicación Lógica

1. Configurar el Publicador (Servidor Primario)

  • Modificaciones en postgresql.conf:

    wal_level = logical
    max_replication_slots = 10 # Para slots de replicación lógica
    max_wal_senders = 10     # Debe ser al menos max_replication_slots
    
  • Crear una Publicación:

    -- En la base de datos del publicador:
    CREATE PUBLICATION my_publication FOR TABLE 
        table1, 
        table2 
        WITH (publish = 'insert,update,delete');
    
    -- O para todas las tablas:
    -- CREATE PUBLICATION all_tables_pub FOR ALL TABLES;
    

    Recarga la configuración en el publicador.

2. Configurar el Suscriptor (Servidor Réplica)

  • Asegúrate de que las tablas de destino existan: La base de datos del suscriptor debe tener las tablas de destino con el mismo esquema que el publicador. Puedes crearlas manualmente o usar pg_dump para extraer el esquema.

  • Crear una Suscripción:

    -- En la base de datos del suscriptor:
    CREATE SUBSCRIPTION my_subscription
        CONNECTION 'host=publisher_host_ip port=5432 user=replication_user password=your_password dbname=publisher_db'
        PUBLICATION my_publication;
    

    El replication_user necesita permisos apropiados en el publicador.

    PostgreSQL creará automáticamente un slot de replicación en el publicador y comenzará a aplicar los cambios. Puedes monitorear el estado de la suscripción usando pg_stat_subscription en el suscriptor.

Consejo: La replicación lógica utiliza la infraestructura de decodificación lógica incorporada de PostgreSQL. No requiere una extensión separada para publicaciones y suscripciones básicas.

Elegir el Método de Replicación Correcto

  • Replicación en Streaming: Ideal para alta disponibilidad y recuperación ante desastres, donde necesitas una copia exacta, byte por byte, del primario. Es más simple de configurar para la replicación completa de la base de datos y proporciona la mejor escalabilidad de lectura para réplicas de solo lectura.
  • Replicación Lógica: Más adecuada para distribución selectiva de datos, migraciones, actualizaciones entre versiones, o cuando necesitas replicar solo un subconjunto de datos. Permite escenarios más complejos como replicar a diferentes esquemas o realizar transformaciones de datos.

Conclusión

Usa replicación en streaming cuando necesites un standby completo para conmutación por error, recuperación ante desastres o tráfico de solo lectura. Usa replicación lógica cuando necesites tablas seleccionadas, migración entre versiones o movimiento controlado de datos entre diferentes bases de datos.

Antes de confiar en cualquiera de las configuraciones, realiza un simulacro de conmutación por error, verifica el manejo de conexiones de la aplicación, monitorea el retraso de replicación y asegúrate de que las copias de seguridad aún se restauren correctamente. La replicación mantiene otro servidor actualizado; no reemplaza las pruebas operativas.