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:
- AWS CLI configurado con tus access y secret keys.
- Conectividad hacia las instancias de RDS.
- Un Security Group (SG) de VPC ya existente que permita a tu IP conectarse al puerto
5432.
Pasos generales
- Crear y configurar parameter groups con los parámetros requeridos.
- Aprovisionar instancias de RDS: crea las instancias de RDS PostgreSQL.
- Configurar la replicación lógica: define slots, publicaciones y suscripciones.
- Simular un failover y actualizar la suscripción: promueve la read replica y redirige la suscripción hacia la nueva primaria.
- Probar el flujo de replicación para asegurar la consistencia de los datos.
- 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: