Liberar espacio en disco en RDS PostgreSQL por replicación lógica

Recientemente me encontré con un problema crítico en una base de datos RDS PostgreSQL. Mientras estábamos intentando configurar la replicación lógica en un PostgreSQL la instancia se quedó sin espacio en disco, lo que provocó errores como

could not extend file "base/XXXXX/XXXXX": No space left on device

Este post detalla los pasos que seguí para diagnosticar y liberar espacio, con un enfoque especial en la replicación lógica y los replication slots inactivos.

Diagnóstico inicial: sin espacio y sin acceso

El primer síntoma fue que no podía ni conectarme a la base de datos, ni siquiera desde la consola de RDS. Para poder avanzar:

  1. Amplié el volumen de almacenamiento manualmente desde la consola de AWS, añadiendo 10 GB.
  2. Apliqué los cambios y reinicié la instancia.
  3. Tras esto, volví a tener acceso a la RDS y pude investigar.

Haz esto solo en el caso de que no puedas conectar de ninguna manera. De lo contrario son gigas que vas a tener ahí gastando sin necesidad.

Paso 1: Identificar el uso de disco por WAL (Write Ahead Logs)

En CloudWatch observé que la métrica TransactionLogsDiskUsage había crecido significativamente.

Uno de los motivos comunes para esto es la presencia de replication slots que no están siendo consumidos, pero siguen reteniendo WAL indefinidamente.

Paso 2: Consultar los replication slots

Conectado vía psql, ejecuté:

SELECT slot_name,pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) AS replicationSlotLag,active FROM pg_replication_slots;

Resultado:

slot_name                          | replicationslotlag | active
----------------------------------+---------------------+--------
my_database_000...                 | 39 GB               | f

Esto mostraba un slot inactivo (active = f) acumulando 39 GB de WAL, sin ser consumido por ninguna suscripción activa.

Paso 3: Eliminar el replication slot inactivo

Importante!: Aunque se escribe como SELECT pg_drop_replication_slot('slot_name'), es equivalente a una orden de eliminación del slot lógico y no devuelve resultados útiles salvo confirmación.

Una vez identificado que no estaba en uso:

SELECT pg_drop_replication_slot('my_database_00016404_11160f1c_09c4_4fee_b442_053d14aadb09')+

Verifiqué después que no quedaban slots:

SELECT * FROM pg_replication_slots

Paso 4: Comprobar publicaciones y suscripciones

Aunque el slot se eliminó, también revisé si quedaban publicaciones o suscripciones residuales:

Publicaciones:

SELECT * FROM pg_publication

Resultado:

pubname    | my_pub

Como ya no estaba usando replicación lógica, la eliminé:

DROP PUBLICATION my_pub

Suscripciones (si fuese una base destino):

SELECT * FROM pg_subscription

(No se encontró ninguna en mi caso.)

Paso 5: Desactivar la replicación lógica (opcional)

Si no tienes previsto usar replicación lógica próximamente, considera desactivar la opción en el parámetro group:

rds.logical_replication = 0

Este cambio requiere reiniciar la instancia.

Conclusiones

Gracias a estos pasos logré liberar más de 39 GB ocupados por WAL retenidos y estabilizar el estado de la base de datos. Lecciones clave:

  • Siempre monitorea TransactionLogsDiskUsage y FreeStorageSpace en CloudWatch.
  • Los replication slots inactivos pueden acumular decenas de GB.
  • La replicación lógica debe limpiarse cuidadosamente tras pruebas.
  • Configura alarmas para evitar quedarte sin espacio de forma silenciosa.

Links

Leave a Reply

Your email address will not be published. Required fields are marked *