Publicações e Assinaturas
Publicações definem quais alterações saem do publicador; assinaturas conectam um assinante a uma ou mais publicações e controlam o comportamento da cópia inicial.
Receita
Publique um subconjunto de colunas com filtro de linha (PostgreSQL 18).
-- Lista de colunas + filtro de linha no 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;Quando usar isso: Fan-out multi-tenant, sincronização parcial de tabelas ou ocultação de colunas sensíveis de um armazenamento downstream.
Exemplo de Trabalho
Múltiplas publicações, uma assinatura e preparação de esquema no assinante:
-- Publicador
CREATE PUBLICATION core_pub FOR TABLE customers, orders;
CREATE PUBLICATION audit_pub FOR TABLE audit_log;
-- O esquema do assinante deve existir antes que a assinatura 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);-- Adicionar tabela a uma publicação existente
ALTER PUBLICATION core_pub ADD TABLE order_items;
-- O assinante pega a nova tabela após REFRESH (PostgreSQL 18+)
ALTER SUBSCRIPTION warehouse_sub REFRESH PUBLICATION;O que isso demonstra:
- Publicações podem ter como alvo várias tabelas; assinaturas podem consumir várias publicações.
- Tabelas do assinante devem existir com colunas compatíveis antes que a aplicação comece.
ALTER PUBLICATION ... ADD TABLErequerREFRESH PUBLICATIONno assinante.
Mergulho Profundo
Opções de Publicação
| Recurso | Sintaxe | Notas |
|---|---|---|
| Todas as tabelas | FOR ALL TABLES | Inclui tabelas futuras no mesmo BD |
| Lista de tabelas | FOR TABLE t1, t2 | Lista explícita permitida |
| Lista de colunas | FOR TABLE t (c1, c2) | A tabela do assinante pode omitir colunas não publicadas |
| Filtro de linha | WHERE (predicate) | Filtro no lado do publicador; o predicado deve ser imutável |
Parâmetros de Assinatura
| Parâmetro | Valor Típico | Propósito |
|---|---|---|
copy_data | true / false | Cópia inicial da tabela |
create_slot | true | Cria um slot lógico no publicador |
enabled | true | Pausa com false durante a manutenção |
streaming | on | Transmite transações em andamento (PG 18) |
synchronous_commit | off no assinante | Aplicação mais rápida; RPO mais amplo no assinante |
Gerenciando o Ciclo de Vida
-- Pausar aplicação
ALTER SUBSCRIPTION warehouse_sub DISABLE;
ALTER SUBSCRIPTION warehouse_sub SET (enabled = false);
-- Remover de forma limpa (remove o slot no publicador se for proprietário)
DROP SUBSCRIPTION warehouse_sub;Armadilhas
- Filtro de linha não imutável - A criação da publicação falha ou o comportamento é indefinido. Correção: Use apenas expressões estáveis; sem funções voláteis.
- Incompatibilidade da lista de colunas - Erros de aplicação se os tipos de coluna do assinante diferirem. Correção:
LIKE ... INCLUDING ALLdo dump do esquema do publicador. - Surpresas com FOR ALL TABLES - Nova tabela sensível é replicada automaticamente. Correção: Prefira listas explícitas de tabelas em ambientes regulamentados.
- Esqueceu REFRESH após ADD TABLE - Nova tabela nunca é copiada. Correção:
ALTER SUBSCRIPTION ... REFRESH PUBLICATIONe verifiquepg_subscription_rel. - DROP SUBSCRIPTION sem conexão - Slot lógico órfão no publicador. Correção: Remova do publicador:
pg_drop_replication_slotse necessário.
Alternativas
| Alternativa | Usar Quando | Não Usar Quando |
|---|---|---|
FOR ALL TABLES IN SCHEMA | Sincronização com escopo de esquema | Colunas parciais entre esquemas |
| Publicações por inquilino | Isolamento rígido por inquilino | Centenas de inquilinos (sobrecarga operacional) |
| Atualização de view materializada | Análise em lote | Requisitos quase em tempo real |
FAQs
Filtros podem referenciar variáveis de sessão?
Não. Filtros de linha devem ser expressões imutáveis avaliáveis apenas no publicador.
Replicação de Truncate?
PostgreSQL 18 suporta truncate publish para tabelas listadas. Certifique-se de que o assinante espera eventos de truncate.
Replicação entre bancos de dados?
A replicação lógica é dentro de um banco de dados por conexão de assinatura. Use várias assinaturas para vários bancos de dados no mesmo host publicador.
Como renomear uma assinatura?
Remova e recrie, ou use ALTER SUBSCRIPTION ... RENAME TO. Planeje uma breve interrupção durante a recriação.
PgBouncer e assinaturas?
Assinaturas usam conexões persistentes de protocolo de replicação. Não roteie conexões de assinatura através do PgBouncer com pooling de transações.
Relacionados
- Noções Básicas de Replicação Lógica - arquitetura
- Lógica vs. Física - quando usar lógica
- Atualizar com Replicação Lógica - padrão de corte
- Melhores Práticas de Replicação Lógica - armadilhas de DDL
Versões da Stack: Esta página foi escrita para PostgreSQL 18.4 (estável 18, manutenção 17), pgvector 0.8+, PgBouncer 1.x, Patroni 3.x e PostGIS 3.5+.