Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

Más confiabilidad en PostgreSQL 17 con failover de replicación lógica

By Aamir HaroonJan 20, 20255 min read

Esta página también está disponible en English, Deutsch, Français, Italiano, 日本語 y Português.

PostgreSQL 17 incorporó el parámetro sync_replication_slot, una función que cambia las reglas del juego para mantener la continuidad de la replicación lógica durante un failover o un upgrade mayor. Con esta función, el impacto en los sistemas downstream que dependen de la replicación lógica es mínimo, a diferencia de versiones anteriores de PostgreSQL, donde se requería una resincronización completa. En este blog te muestro cómo configurar y probar sync_replication_slots con instancias de Amazon Relational Database Service (RDS) en un escenario real.

Vamos a recorrer un escenario con tres instancias de RDS PostgreSQL:

  • Primaria (PRI): base de datos de origen
  • Read Replica (RR): réplica en standby que se promueve durante el failover
  • Réplica lógica (LR): instancia suscriptora que depende de la replicación lógica desde la primaria

Requisitos previos

Antes de empezar, asegúrate de contar con:

  1. AWS CLI configurado con tus access y secret keys.
  2. Conectividad hacia las instancias de RDS.
  3. Un Security Group (SG) de VPC ya existente que permita a tu IP conectarse al puerto 5432.

Pasos generales

  1. Crear y configurar parameter groups con los parámetros requeridos.
  2. Aprovisionar instancias de RDS: crea las instancias de RDS PostgreSQL.
  3. Configurar la replicación lógica: define slots, publicaciones y suscripciones.
  4. Simular un failover y actualizar la suscripción: promueve la read replica y redirige la suscripción hacia la nueva primaria.
  5. Probar el flujo de replicación para asegurar la consistencia de los datos.
  6. Limpiar los recursos.

Recorrido paso a paso

1. Configurar los parameter groups

  • Primero, crea parameter groups personalizados para la primaria, la read replica y la réplica lógica. Habilita los siguientes parámetros:
| Parámetro                    | Valor     | Descripción                                                                    |
|------------------------------|-----------|--------------------------------------------------------------------------------|
| rds.logical_replication      | 1         | Habilita la replicación lógica en la instancia primaria.                       |
| hot_standby_feedback         | 1         | Evita conflictos en consultas al enviar feedback desde la standby a la primaria. |
| rds.logical_slot_sync_dbname | DB válida | Indica la base de datos para la sincronización de slots (default: `postgres`). |
| synchronized_standby_slots   | Slot name | Nombre del slot de replicación física de la standby que debe permanecer sincronizada. |
| sync_replication_slots       | 1         | Habilita la sincronización automática de los slots de replicación.             |

Crea el parameter group. Repite pasos similares para la read replica y la réplica lógica.

aws rds create-db-parameter-group \
    --db-parameter-group-name pg-primary-group \
    --db-parameter-group-family postgres17 \
    --description "Logical replication setup with sync_replication_slots"
  • Modifica los parámetros. El valor de synchronized_standby_slots se definirá una vez creada la read replica:
aws rds modify-db-parameter-group \
    --db-parameter-group-name pg-primary-group \
    --parameters "ParameterName='rds.logical_replication',ParameterValue=logical,ApplyMethod=pending-reboot" \
                 "ParameterName='sync_replication_slots',ParameterValue=1,ApplyMethod=pending-reboot"
aws rds modify-db-parameter-group \
    --db-parameter-group-name pg-read-replica-group \
    --parameters "ParameterName='rds.logical_replication',ParameterValue=1,ApplyMethod=pending-reboot" \
                 "ParameterName='hot_standby_feedback',ParameterValue='1',ApplyMethod=pending-reboot" \
                 "ParameterName='rds.logical_slot_sync_dbname',ParameterValue='postgres',ApplyMethod=pending-reboot" \
                 "ParameterName='sync_replication_slots',ParameterValue=1,ApplyMethod=pending-reboot"

2. Aprovisionar las instancias de RDS

  • Con AWS CLI, crea la instancia primaria, la réplica lógica y la read replica. Para fines de prueba, estas instancias serán accesibles públicamente:
aws rds create-db-instance \
    --db-instance-identifier primary-instance \
    --engine postgres \
    --engine-version 17.1 \
    --allocated-storage 20 \
    --master-username postgres \
    --master-user-password ChangeM3 \
    --db-instance-class db.t3.medium \
    --vpc-security-group-ids sg-xxxxxx

Repite el paso anterior para la réplica lógica.

  • Para la read replica:
aws rds create-db-instance-read-replica \
    --db-instance-identifier read-replica \
    --source-db-instance-identifier primary-instance
  • Una vez creada la read replica, obtén el nombre del slot físico desde la instancia primaria y actualiza el parameter group pg-primary-group:
psql -h $DB_PRI -U postgres -t -c "SELECT slot_name FROM pg_replication_slots where slot_type='physical'"

aws rds modify-db-parameter-group \
    --db-parameter-group-name pg-primary-group \
    --parameters "ParameterName='synchronized_standby_slots',ParameterValue='rds_us_east_1_db_dn2uyr2436rexq3u7gcdfzw4hy',ApplyMethod=pending-reboot"
  • Asigna ahora los parameter groups a las instancias correspondientes y reinícialas.
  • Verifica que los parámetros queden bien configurados. Estos valores son indispensables para que la replicación lógica siga funcionando tras el failover:
psql -h $DB_PRI -U postgres -c "SELECT name,setting FROM pg_settings WHERE name IN ('wal_level','rds.logical_replication','sync_replication_slots','synchronized_standby_slots')"
:' output
            name            |                   setting
----------------------------+---------------------------------------------
 rds.logical_replication    | on
 sync_replication_slots     | on
 synchronized_standby_slots | rds_us_east_1_db_dn2uyr2436rexq3u7gcdfzw4hy
 wal_level                  | logical
(4 rows)
'

# rds.logical_slot_sync_dbname no aparece en pg_settings
# asegúrate de actualizarlo si tu base de datos no es "postgres."
psql -h $DB_RR -U postgres -c "SELECT name,setting FROM pg_settings WHERE name IN ('wal_level','rds.logical_replication','sync_replication_slots','hot_standby_feedback','rds.logical_slot_sync_dbname')"
:' output
          name           | setting
-------------------------+---------
 hot_standby_feedback    | on
 rds.logical_replication | on
 sync_replication_slots  | on
 wal_level               | logical
(4 rows)
'

3. Configurar la replicación lógica

En la instancia primaria:

  • Crea la tabla de origen, carga datos de muestra y crea la publicación:
CREATE TABLE reptab1 (slno int primary key);
INSERT INTO reptab1 VALUES (generate_series(1,1000));
CREATE PUBLICATION testpub FOR TABLE reptab1;
  • Crea una tabla idéntica y una suscripción con failover = true en la réplica lógica. Con esto se creará un slot de replicación lógica en la primary-instance.
CREATE TABLE reptab1 (slno int primary key);
CREATE SUBSCRIPTION testsub CONNECTION 'host=<primary-endpoint> port=5432 dbname=postgres user=postgres password=ChangeM3' PUBLICATION testpub WITH (failover = true);
  • Verifica que la suscripción esté activa y que los datos se hayan copiado:
SELECT subname, subenabled FROM pg_subscription;
SELECT count(*) from reptab1;
  • Deberías ver un slot de replicación lógica en la instancia read-replica:
psql -h $DB_RR -U postgres -c "select slot_name, slot_type, active, failover, synced from pg_replication_slots;"
:'output
 slot_name | slot_type | active | failover | synced
-----------+-----------+--------+----------+--------
 testsub   | logical   | f      | t        | t
(1 row)
'

4. Simular el failover y actualizar la suscripción

Para simular un failover:

  • Promueve la read replica a una instancia independiente:
aws rds promote-read-replica \
   --db-instance-identifier read-replica
  • Actualiza la suscripción en la réplica lógica para que apunte a la nueva primaria:
ALTER SUBSCRIPTION testsub CONNECTION 'host=<read-replica-endpoint> port=5432 dbname=postgres user=postgres password=ChangeM3';

5\. Probar los resultados

Con sync_replication_slots habilitado, el slot de replicación lógica se preserva durante el failover, lo que le permite al suscriptor (la réplica lógica) seguir replicando sin interrupciones y sin tener que resincronizar.

  • Inserta nuevas filas en la read replica promovida para validar la replicación:
INSERT INTO reptab1 VALUES (generate_series(1001,2000));
  • Verifica que la réplica lógica contenga las filas actualizadas:
SELECT COUNT(*) FROM reptab1;  -- Debe reflejar los nuevos datos

6\. Limpieza

Para no incurrir en costos de recursos, elimina todas las instancias de RDS y los parameter groups:

aws rds delete-db-instance --db-instance-identifier primary-instance --skip-final-snapshot
aws rds delete-db-instance --db-instance-identifier read-replica --skip-final-snapshot
aws rds delete-db-instance --db-instance-identifier logical-replica --skip-final-snapshot

aws rds delete-db-parameter-group --db-parameter-group-name pg-primary-group
aws rds delete-db-parameter-group --db-parameter-group-name pg-read-replica-group
aws rds delete-db-parameter-group --db-parameter-group-name pg-logical-replica-group

El parámetro sync_replication_slots de PostgreSQL 17 mejora notablemente la resiliencia de la replicación lógica al mantener los slots sincronizados a lo largo de los failovers. Es una ventaja enorme en escenarios donde la consistencia de los datos y reducir el downtime al mínimo resultan críticos. En este artículo te mostré cómo la replicación lógica puede continuar sin interrupciones al simular un failover y redirigir las suscripciones.

En entornos de producción conviene sumar otras consideraciones —como cifrado, despliegues multi-AZ y monitoreo— para lograr una configuración robusta.

Si quieres ver el ejemplo completo en funcionamiento, aquí tienes el script: https://gist.github.com/aamir814/092ed85bd90e28d79af029e561c1da88

Si necesitas ayuda con esta función o con cualquier otro tema de PostgreSQL, nuestro equipo está formado exclusivamente por Engineers senior. En DoiT International nos especializamos en consultoría avanzada en la nube, diseño de arquitectura y servicios de debugging. Ya sea que estés dando tus primeros pasos con bases de datos distribuidas, optimizando un sistema existente o resolviendo problemas complejos, te brindamos asesoría experta a la medida.

Contáctanos hoy y te ayudamos a aprovechar todo el potencial de tu infraestructura en la nube.

Referencias: