Oracle GoldenGate 26ai com PostgreSQL: o que são Publications e como elas funcionam

Autor(a):

Quem já trabalha com Oracle GoldenGate em bancos Oracle está acostumado com conceitos como Extract, trail, Replicat, supplemental logging e checkpoint. Quando entramos no mundo do PostgreSQL, a arquitetura geral continua familiar, mas aparecem alguns componentes novos no caminho.

Um deles é a Publication.

E ela costuma chamar a atenção justamente quando alguma coisa não funciona. Você configura um Extract para usar o plugin pgoutput, tenta iniciá-lo e recebe uma mensagem parecida com esta:

OGG-30584 Oracle GoldenGate Capture for PostgreSQL:
Extract configured by client to use pgoutput plugin.
The supplied publication name is not available in the database.

Nesse momento surgem várias perguntas:

  • O que é uma Publication?
  • Ela é um objeto do GoldenGate ou do PostgreSQL?
  • Qual é a diferença entre Publication e replication slot?
  • Por que ela é necessária com pgoutput?
  • E onde entra o ADD TRANDATA nessa história?

É exatamente isso que vamos entender neste artigo. Sem complicar desnecessariamente, mas também sem ficar apenas na superfície.

Antes de tudo: a Publication é do PostgreSQL

A primeira coisa que precisamos deixar clara é que a Publication não é um objeto criado pelo Oracle GoldenGate.

Ela é um objeto nativo do PostgreSQL, utilizado pela infraestrutura de replicação lógica do banco.

De maneira simples, uma Publication define:

  • quais tabelas terão suas alterações disponibilizadas;
  • quais tipos de operação serão publicados;
  • qual conjunto de dados poderá ser consumido por um assinante ou por uma ferramenta de CDC, como o GoldenGate.

Pense nela como uma lista de conteúdo que o PostgreSQL está autorizado a publicar.

Ela não armazena linhas, não mantém o checkpoint do GoldenGate e também não é uma fila de transações. Sua função é declarar quais mudanças podem participar daquele fluxo de replicação lógica.

Para que serve uma Publication?

Imagine um database PostgreSQL com centenas de tabelas. Você provavelmente não quer enviar todas elas para todos os consumidores de CDC.

Uma aplicação pode precisar apenas das tabelas de vendas. Outra integração pode consumir somente os dados financeiros. Um terceiro processo pode precisar de todas as tabelas do database.

As Publications permitem organizar essa seleção.

Por exemplo, podemos criar uma Publication somente para algumas tabelas:

CREATE PUBLICATION pub_vendas
FOR TABLE vendas.pedidos,
          vendas.itens_pedido,
          cadastro.clientes;

Também podemos publicar todas as tabelas do database:

CREATE PUBLICATION pub_ogg
FOR ALL TABLES;

Além das tabelas, podemos controlar os tipos de operação publicados:

CREATE PUBLICATION pub_vendas
FOR TABLE vendas.pedidos
WITH (
    publish = 'insert,update,delete'
);

Por padrão, uma Publication pode publicar:

  • INSERT;
  • UPDATE;
  • DELETE;
  • TRUNCATE.

Portanto, a Publication funciona como uma definição lógica do conjunto de alterações que será disponibilizado pelo PostgreSQL.

Onde o pgoutput entra nessa arquitetura?

Para transformar as informações do WAL em eventos compreensíveis por um consumidor de replicação lógica, o PostgreSQL utiliza um logical decoding output plugin.

No nosso cenário, esse plugin é o pgoutput.

O pgoutput é o plugin nativo utilizado pelo mecanismo de replicação lógica do PostgreSQL. Ele consulta uma ou mais Publications para saber quais tabelas e operações devem ser enviadas ao consumidor.

No GoldenGate 26ai, o fluxo fica parecido com este:

WAL do PostgreSQL
        ↓
Publication
        ↓
pgoutput
        ↓
Replication slot
        ↓
OGG Extract
        ↓
Trail
        ↓
Replicat

Cada componente tem uma responsabilidade bem definida:

ComponenteResponsabilidade
WALRegistra as alterações realizadas no PostgreSQL
PublicationDefine quais tabelas e operações serão publicadas
pgoutputConverte as alterações do WAL para o protocolo de replicação lógica
Replication slotMantém a posição de consumo e protege o WAL ainda necessário
ExtractConsome as alterações e grava o trail do GoldenGate
ReplicatLê o trail e aplica as alterações no destino

Essa separação ajuda a entender um detalhe importante: Publication e replication slot não são a mesma coisa.

Publication não é replication slot

Essa confusão é bastante comum no começo.

A Publication responde à pergunta:

Quais alterações estão disponíveis para publicação?

O replication slot responde a outra pergunta:

Até qual posição o consumidor já processou o WAL?

O slot mantém informações como:

  • plugin utilizado;
  • database ao qual pertence;
  • posição inicial necessária no WAL;
  • posição confirmada pelo consumidor;
  • estado ativo ou inativo.

Podemos consultar os slots assim:

SELECT slot_name,
       plugin,
       slot_type,
       database,
       active,
       restart_lsn,
       confirmed_flush_lsn
FROM pg_replication_slots
ORDER BY slot_name;

Um resultado usando o GoldenGate com pgoutput pode ser semelhante a este:

slot_name  plugin    slot_type  database     active
---------  --------  ---------  -----------  ------
ext02      pgoutput  logical    oggdatabase  true

O slot evita que o PostgreSQL remova segmentos de WAL que ainda podem ser necessários pelo consumidor. Por isso, um slot abandonado ou um Extract parado por muito tempo pode provocar crescimento da área de WAL.

Ou seja: Publication decide o que publicar; replication slot controla de onde o consumidor continua.

pgoutput versus test_decoding

Outro ponto que merece atenção é que pgoutput e test_decoding não são tipos de Publication. Eles são output plugins diferentes.

O pgoutput:

  • é nativo do PostgreSQL;
  • foi desenvolvido para replicação lógica;
  • trabalha com Publications;
  • transmite mensagens estruturadas pelo protocolo de replicação lógica;
  • é a escolha natural para novas configurações do GoldenGate 26ai.

O test_decoding:

  • foi criado principalmente como exemplo e ferramenta de teste do logical decoding;
  • produz uma representação textual das alterações;
  • não trabalha com Publications da mesma maneira;
  • pode não estar disponível em alguns serviços gerenciados de PostgreSQL;
  • permanece relevante principalmente para compatibilidade com configurações existentes.

Existe aqui um detalhe capaz de causar bastante confusão. Ao criar um Extract pela interface web do GoldenGate 26ai, o wizard apresenta o pgoutput como padrão para PostgreSQL. No Admin Client, se o plugin não for informado explicitamente no registro, o comportamento documentado pode resultar no uso do test_decoding.

Para evitar ambiguidade, registre explicitamente o plugin:

REGISTER EXTRACT EXT02 PGPLUGINTYPE pgoutput

Podemos confirmar qual plugin foi associado ao slot consultando pg_replication_slots.

Como criar uma Publication para o GoldenGate

Vamos considerar um database chamado oggdatabase e uma Publication chamada pub_ogg.

Primeiro, conecte-se ao database correto:

psql -h servidor -p 5432 -U usuario -d oggdatabase

Esse detalhe é importante porque a Publication pertence a um database específico. Criar pub_ogg no database postgres não a torna disponível em oggdatabase, mesmo que os dois estejam na mesma instância.

Para publicar todas as tabelas:

CREATE PUBLICATION pub_ogg
FOR ALL TABLES;

Para publicar somente algumas tabelas:

CREATE PUBLICATION pub_ogg
FOR TABLE public.clientes,
          public.pedidos,
          public.itens_pedido;

Depois, valide a configuração:

SELECT pubname,
       puballtables,
       pubinsert,
       pubupdate,
       pubdelete,
       pubtruncate
FROM pg_publication
WHERE pubname = 'pub_ogg';

Para conferir as tabelas efetivamente abrangidas:

SELECT pubname,
       schemaname,
       tablename
FROM pg_publication_tables
WHERE pubname = 'pub_ogg'
ORDER BY schemaname, tablename;

Como informar a Publication no Extract

Com a Publication criada, precisamos informá-la no parameter file do Extract:

EXTRACT EXT02
USERIDALIAS alias_pg DOMAIN OracleGoldenGate

EXTTRAIL source_db/aa

TRANLOGOPTIONS STREAMINGOPTIONS (publication_names="pub_ogg";)

TABLE public.*;

Observe com atenção a posição do ponto e vírgula:

publication_names="pub_ogg";
                           ^
                 fora das aspas

Não use:

publication_names="pub_ogg;"

Nesse caso, o ponto e vírgula pode acabar sendo interpretado como parte do nome fornecido.

Também é possível informar várias Publications, de acordo com a sintaxe suportada:

TRANLOGOPTIONS STREAMINGOPTIONS (
    publication_names="pub_vendas,pub_cadastro";
)

Publication e TABLE fazem a mesma coisa?

Não exatamente.

Os dois mecanismos participam da seleção dos dados, mas atuam em camadas diferentes.

ConfiguraçãoOnde atuaFunção
PublicationPostgreSQLDefine o que o pgoutput disponibiliza
TABLEGoldenGate ExtractDefine o que o Extract captura e grava no trail

Se o parameter file tiver:

TABLE public.pedidos;

mas public.pedidos não estiver incluída na Publication, o PostgreSQL não enviará suas alterações naquela sessão de replicação.

Por outro lado, uma tabela pode estar na Publication e não aparecer em nenhum comando TABLE do Extract. Nesse caso, ela pode estar disponível no fluxo do PostgreSQL, mas será descartada pela seleção do GoldenGate.

Para evitar surpresas, mantenha coerência entre a Publication e as cláusulas TABLE.

E onde entra o ADD TRANDATA?

No PostgreSQL, o ADD TRANDATA tem um significado diferente do supplemental logging tradicional do Oracle Database.

O comando atua sobre o REPLICA IDENTITY da tabela. Essa propriedade determina quais valores anteriores de uma linha serão registrados no WAL para operações de UPDATE e DELETE.

No Admin Client:

DBLOGIN USERIDALIAS alias_pg DOMAIN OracleGoldenGate

ADD TRANDATA public.clientes

Para todas as tabelas atuais do schema:

ADD TRANDATA public.*

Para registrar todas as colunas anteriores:

ADD TRANDATA public.clientes ALLCOLS

No PostgreSQL, ALLCOLS configura REPLICA IDENTITY FULL:

ALTER TABLE public.clientes REPLICA IDENTITY FULL;

Isso pode ser necessário para tabelas sem chave adequada ou para cenários que exigem before images completas. Porém, não é uma configuração gratuita: FULL pode aumentar o volume de WAL, especialmente em tabelas largas e com muitos UPDATE ou DELETE.

Para uma replicação unidirecional simples, tabelas com uma chave adequada normalmente podem trabalhar com REPLICA IDENTITY DEFAULT. Para casos de CDR, registros não comprimidos ou necessidade de todas as imagens anteriores, avalie ALLCOLS.

Podemos verificar pelo GoldenGate:

INFO TRANDATA public.clientes

Ou diretamente no PostgreSQL:

SELECT n.nspname AS schema_name,
       c.relname AS table_name,
       CASE c.relreplident
           WHEN 'd' THEN 'DEFAULT'
           WHEN 'n' THEN 'NOTHING'
           WHEN 'f' THEN 'FULL'
           WHEN 'i' THEN 'USING INDEX'
       END AS replica_identity
FROM pg_class c
JOIN pg_namespace n
  ON n.oid = c.relnamespace
WHERE n.nspname = 'public'
  AND c.relkind IN ('r', 'p')
ORDER BY c.relname;

Um detalhe operacional: CREATE PUBLICATION ... FOR ALL TABLES inclui automaticamente novas tabelas na Publication. Já um ADD TRANDATA public.* atua sobre as tabelas encontradas quando o comando é executado. Portanto, novas tabelas ainda precisam ter sua REPLICA IDENTITY validada.

Exemplo completo no GoldenGate 26ai

Vamos juntar as peças.

1. Criar a Publication

No database de origem:

CREATE PUBLICATION pub_ogg
FOR ALL TABLES;

2. Conectar o Admin Client

CONNECT https://ogg-host:16000 \
    DEPLOYMENT pg_source \
    AS ggadmin PASSWORD senha

DBLOGIN USERIDALIAS alias_pg DOMAIN OracleGoldenGate

3. Configurar o TRANDATA

ADD TRANDATA public.*
INFO TRANDATA public.*

4. Registrar explicitamente com pgoutput

REGISTER EXTRACT EXT02 PGPLUGINTYPE pgoutput

O registro cria e associa o replication slot lógico necessário ao Extract.

5. Criar o Extract e o trail

ADD EXTRACT EXT02, TRANLOG, BEGIN NOW
ADD EXTTRAIL source_db/aa, EXTRACT EXT02

6. Configurar o parameter file

EXTRACT EXT02
USERIDALIAS alias_pg DOMAIN OracleGoldenGate

EXTTRAIL source_db/aa

TRANLOGOPTIONS STREAMINGOPTIONS (publication_names="pub_ogg";)

TABLE public.*;

7. Validar e iniciar

INFO EXTRACT EXT02, DETAIL
START EXTRACT EXT02
VIEW REPORT EXT02

Diagnosticando o erro OGG-30584

Quando o GoldenGate informa que a Publication não está disponível, siga esta sequência.

Confirme o database

SELECT current_database(),
       current_user,
       inet_server_addr(),
       inet_server_port();

É perfeitamente possível ter databases com o mesmo nome em instâncias ou endpoints diferentes. O alias do GoldenGate precisa apontar para o mesmo ambiente em que a Publication foi criada.

Confirme a Publication

SELECT pubname
FROM pg_publication
WHERE pubname = 'pub_ogg';

Confirme letras maiúsculas e minúsculas

Estes dois comandos criam nomes diferentes:

CREATE PUBLICATION pub_ogg FOR ALL TABLES;
CREATE PUBLICATION "PUB_OGG" FOR ALL TABLES;

Consulte o nome exato:

SELECT pubname, quote_ident(pubname)
FROM pg_publication;

Confira o parameter file

VIEW PARAMS EXT02

Procure por espaços, aspas e pelo ponto e vírgula:

TRANLOGOPTIONS STREAMINGOPTIONS (publication_names="pub_ogg";)

Confira o slot e o plugin

SELECT slot_name,
       plugin,
       database,
       active,
       restart_lsn,
       confirmed_flush_lsn
FROM pg_replication_slots;

Para esse cenário, esperamos encontrar plugin = pgoutput e database = oggdatabase.

Cuidados importantes em produção

Antes de encerrarmos, vale deixar alguns alertas práticos.

Monitore o replication slot

Se o Extract ficar parado, o PostgreSQL poderá reter WAL necessário ao slot. Monitore restart_lsn, confirmed_flush_lsn e o volume de WAL retido.

Não exclua uma Publication usada por um Extract ativo

Excluir a Publication durante o funcionamento pode interromper a captura. A documentação do GoldenGate alerta que a exclusão pode tornar o slot impactado inutilizável, exigindo uma nova Publication e um novo slot.

Crie a Publication antes de registrar o Extract

Essa é a sequência recomendada para pgoutput: primeiro a Publication, depois o REGISTER EXTRACT.

Avalie bem o REPLICA IDENTITY FULL

Ele resolve problemas de identificação de linhas e fornece before images completas, mas pode aumentar significativamente o WAL. Use quando o requisito justificar.

Monitore tabelas novas

Uma Publication FOR ALL TABLES alcança tabelas novas, mas sua política de TRANDATA e REPLICA IDENTITY também precisa acompanhá-las.

Conclusão

Quando usamos Oracle GoldenGate com PostgreSQL, entender apenas Extract, trail e Replicat não é suficiente. Precisamos conhecer também alguns componentes nativos do PostgreSQL.

A Publication define quais alterações podem ser publicadas. O pgoutput transforma essas alterações em mensagens de replicação lógica. O replication slot mantém a posição de leitura e a retenção necessária do WAL. O REPLICA IDENTITY, configurado pelo ADD TRANDATA, determina quais informações anteriores estarão disponíveis para identificar as linhas modificadas.

Quando essas peças estão alinhadas, a arquitetura deixa de parecer misteriosa:

Publication → seleciona
pgoutput → decodifica
Replication slot → controla a posição
Extract → captura
Trail → transporta
Replicat → aplica

E aquele erro que parecia apenas mais uma mensagem obscura do GoldenGate passa a fazer sentido.

Mais do que decorar comandos, o importante é entender a responsabilidade de cada componente. É isso que permite diagnosticar rapidamente por que uma configuração funciona pela interface web, mas falha quando é criada manualmente pelo Admin Client.

Referências

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *