Publicaciones y Suscripciones
Las publicaciones definen qué cambios salen del publicador; las suscripciones conectan un suscriptor a una o más publicaciones y controlan el comportamiento de la copia inicial.
Receta
Publicar un subconjunto de columnas con filtro de filas (PostgreSQL 18).
-- Lista de columnas + filtro de filas en el publicador
CREATE PUBLICATION events_pub FOR TABLE events (id, tenant_id, payload, created_at)
WHERE (tenant_id = 42);
CREATE SUBSCRIPTION events_sub
CONNECTION 'host=primary dbname=appdb user=repl password=secret'
PUBLICATION events_pub;Cuándo usar esto: Fan-out multi-inquilino, sincronización parcial de tablas u ocultar columnas sensibles de un almacén descendente.
Ejemplo de Trabajo
Múltiples publicaciones, una suscripción y preparación del esquema en el suscriptor:
-- Publicador
CREATE PUBLICATION core_pub FOR TABLE customers, orders;
CREATE PUBLICATION audit_pub FOR TABLE audit_log;
-- El esquema del suscriptor debe existir antes de que la suscripción aplique DML
CREATE TABLE customers (LIKE public.customers INCLUDING ALL);
CREATE TABLE orders (LIKE public.orders INCLUDING ALL);
CREATE TABLE audit_log (LIKE public.audit_log INCLUDING ALL);
CREATE SUBSCRIPTION warehouse_sub
CONNECTION 'host=primary.db.internal dbname=appdb user=repl_user password=secret sslmode=verify-full'
PUBLICATION core_pub, audit_pub
WITH (copy_data = true, streaming = on);-- Añadir tabla a publicación existente
ALTER PUBLICATION core_pub ADD TABLE order_items;
-- El suscriptor detecta la nueva tabla después de REFRESH (PostgreSQL 18+)
ALTER SUBSCRIPTION warehouse_sub REFRESH PUBLICATION;Lo que esto demuestra:
- Las publicaciones pueden apuntar a múltiples tablas; las suscripciones pueden consumir múltiples publicaciones.
- Las tablas del suscriptor deben existir con columnas compatibles antes de que comience la aplicación.
ALTER PUBLICATION ... ADD TABLErequiereREFRESH PUBLICATIONen el suscriptor.
Análisis Profundo
Opciones de Publicación
| Característica | Sintaxis | Notas |
|---|---|---|
| Todas las tablas | FOR ALL TABLES | Incluye tablas futuras en la misma BD |
| Lista de tablas | FOR TABLE t1, t2 | Lista de permitidos explícita |
| Lista de columnas | FOR TABLE t (c1, c2) | La tabla suscriptora puede omitir columnas no publicadas |
| Filtro de filas | WHERE (predicate) | Filtro en el lado del publicador; el predicado debe ser inmutable |
Parámetros de Suscripción
| Parámetro | Valor típico | Propósito |
|---|---|---|
copy_data | true / false | Copia inicial de la tabla |
create_slot | true | Crea una ranura lógica en el publicador |
enabled | true | Pausa con false durante el mantenimiento |
streaming | on | Transmite transacciones en curso (PG 18) |
synchronous_commit | off en el suscriptor | Aplicación más rápida; mayor RPO en el suscriptor |
Gestión del Ciclo de Vida
-- Pausar aplicación
ALTER SUBSCRIPTION warehouse_sub DISABLE;
ALTER SUBSCRIPTION warehouse_sub SET (enabled = false);
-- Eliminar limpiamente (elimina la ranura en el publicador si es propietaria)
DROP SUBSCRIPTION warehouse_sub;Trampas Comunes
- Filtro de filas no inmutable - La creación de la publicación falla o el comportamiento no está definido. Solución: Usar solo expresiones estables; no funciones volátiles.
- Desajuste en la lista de columnas - Errores de aplicación si los tipos de columna del suscriptor difieren. Solución:
LIKE ... INCLUDING ALLdel volcado del esquema del publicador. - Sorpresas de
FOR ALL TABLES- Nuevas tablas sensibles se replican automáticamente. Solución: Preferir listas de tablas explícitas en entornos regulados. - Olvidó
REFRESHdespués deADD TABLE- La nueva tabla nunca se copia. Solución:ALTER SUBSCRIPTION ... REFRESH PUBLICATIONy verificarpg_subscription_rel. DROP SUBSCRIPTIONsin conexión - Ranura lógica huérfana en el publicador. Solución: Eliminar desde el publicador:pg_drop_replication_slotsi es necesario.
Alternativas
| Alternativa | Usar cuando | No usar cuando |
|---|---|---|
FOR ALL TABLES IN SCHEMA | Sincronización a nivel de esquema | Columnas parciales entre esquemas |
| Publicaciones por inquilino | Aislamiento estricto por inquilino | Cientos de inquilinos (sobrecarga operativa) |
| Actualización de vistas materializadas | Análisis por lotes | Requisitos casi en tiempo real |
Preguntas Frecuentes
¿Pueden los filtros hacer referencia a variables de sesión?
No. Los filtros de filas deben ser expresiones inmutables evaluables solo en el publicador.
¿Replicación de `TRUNCATE`?
PostgreSQL 18 admite TRUNCATE de publicación para las tablas listadas. Asegúrese de que el suscriptor espere eventos de TRUNCATE.
¿Replicación entre bases de datos?
La replicación lógica es dentro de una base de datos por conexión de suscripción. Use suscripciones múltiples para bases de datos múltiples en el mismo host publicador.
¿Cómo renombrar una suscripción?
Eliminar y recrear, o usar ALTER SUBSCRIPTION ... RENAME TO. Planifique un breve lapso durante la recreación.
¿PgBouncer y suscripciones?
Las suscripciones utilizan conexiones persistentes del protocolo de replicación. No enrute las conexiones de suscripción a través de PgBouncer con agrupación de transacciones.
Relacionado
- Conceptos Básicos de Replicación Lógica - arquitectura
- Lógica vs. Física - cuándo usar lógica
- Actualizar con Replicación Lógica - patrón de corte
- Mejores Prácticas de Replicación Lógica - trampas de DDL
Versiones de la pila: Esta página fue escrita para PostgreSQL 18.4 (estable 18, mantenimiento 17), pgvector 0.8+, PgBouncer 1.x, Patroni 3.x y PostGIS 3.5+.