1. Início
  2. Blog
  3. Modernização de legado
Modernização de legado

Change data capture: mantenha dois bancos de dados sincronizados

Change data capture explicado: log, triggers ou polling, ordem, duplicatas, mudanças de schema, CDC vs escrita dupla e quando dispensá-lo numa migração.

Two database cylinders linked by a log tape carrying ordered change events, illustrating change data capture
Nesta página · 7 seções
  1. O que é change data capture (CDC)?
  2. Como o CDC funciona: logs, triggers ou polling?
  3. Por que usar CDC ao migrar uma plataforma no ar?
  4. Quais são as armadilhas comuns: ordem, duplicatas e mudanças de schema?
  5. CDC vs escrita dupla: qual é mais seguro?
  6. Quando change data capture é exagero?
  7. Quer uma segunda opinião sobre a sua migração?

Change data capture (CDC) é uma técnica que detecta cada insert, update e delete em um banco de dados e transmite essas mudanças para outro sistema. O segundo banco de dados fica sincronizado com o primeiro sem ninguém copiar dados manualmente ou rodar exportações noturnas.

Em uma migração com o sistema no ar, o CDC permite que o banco antigo e o novo rodem lado a lado enquanto os usuários continuam trabalhando. Este guia explica como funciona, onde quebra e quando você pode dispensá-lo.

Principais pontos

  • O CDC copia mudanças, não tabelas inteiras, então o destino acompanha a origem com um pequeno atraso.
  • Ler o log do banco de dados costuma ser o método mais confiável. Triggers e polling são mais simples, mas têm custos reais.
  • As partes difíceis são a ordem, as duplicatas e as mudanças de schema, não as ferramentas.
  • O CDC em geral é mais seguro que a escrita dupla, porque o banco de origem continua sendo a única fonte da verdade.
  • Para sistemas pequenos ou com pouco tráfego, uma janela de manutenção e uma exportação simples podem bastar.

O que é change data capture (CDC)?

O CDC transforma um banco de dados em um fluxo de eventos. Cada vez que uma linha muda, um registro descreve o que aconteceu: a tabela, a chave primária, os valores antigos, os valores novos e o tipo de operação.

Um consumidor lê esse fluxo e aplica as mudanças em um destino. O destino pode ser um banco novo em outra engine, um índice de busca, um data warehouse ou um cache.

A ideia central é que a aplicação não precisa saber de nada. O seu código grava no banco exatamente como antes, e a captura acontece por baixo. É isso que torna o CDC atraente quando você está com medo de mexer em uma base de código legada.

Um setup de CDC normalmente tem duas fases:

  1. Snapshot inicial: copiar os dados existentes para o destino.
  2. Streaming contínuo: aplicar cada mudança feita depois do início do snapshot.

Fazer essas duas fases se encontrarem sem lacunas nem sobreposições é onde vai a maior parte do cuidado de engenharia.

Como o CDC funciona: logs, triggers ou polling?

Existem três abordagens comuns. Elas trocam simplicidade por precisão e por carga na origem.

MétodoComo funcionaPrincipal ponto fortePrincipal ponto fraco
Baseado em logLê o log de transações do banco de dados (por exemplo, o logical decoding do PostgreSQL ou o binlog do MySQL)Captura todas as mudanças, inclusive deletes, com pouca cargaExige configuração e permissões no banco de dados
TriggersTriggers do banco gravam as mudanças em uma tabela de auditoriaFunciona em quase qualquer banco de dadosAdiciona overhead a cada escrita e é fácil de esquecer em tabelas novas
PollingUm job consulta linhas com um valor recente de updated_atMuito simples de construirNão enxerga hard deletes nem linhas sem um timestamp confiável

CDC baseado em log

É isso que a maioria dos times quer dizer com CDC. O banco de dados já registra cada mudança confirmada no seu log, para recuperação após falhas e para replicação. Um conector lê esse log e publica eventos. Ferramentas open source como o Debezium fazem isso para vários bancos populares, e os provedores de nuvem oferecem versões gerenciadas.

Triggers e polling

Triggers funcionam bem para um punhado de tabelas. Polling funciona bem quando você só se importa com linhas criadas ou atualizadas e confia nos timestamps. Em uma base de código herdada, eu não confio neles por padrão: scripts em lote, SQL direto e caminhos de código antigos podem atualizar linhas sem tocar na coluna de timestamp, e normalmente você só consegue descartar isso depois de ler todos os caminhos de escrita.

Por que usar CDC ao migrar uma plataforma no ar?

Uma migração com o sistema no ar tem uma restrição dura: o sistema antigo continua recebendo escritas até o dia da virada. Se você copia os dados uma vez, eles já estão desatualizados no momento em que a cópia termina.

O CDC resolve isso mantendo o banco novo atualizado enquanto você constrói e testa o novo sistema com dados reais. Quando tiver confiança, você move o tráfego, e a virada pode se tornar um passo pequeno em vez de um fim de semana de risco.

Na avanzzada, liderei a migração completa de uma plataforma que se candidata automaticamente a vagas de emprego pelos seus usuários, levando toda a arquitetura de uma stack legada para uma nova enquanto as pessoas continuavam usando todos os dias. Nesse tipo de trabalho, a pergunta nunca é só como mover os dados. É como manter dois sistemas contando a mesma história enquanto usuários reais mudam essa história a cada minuto.

Prefiro migrar peça por peça a fazer uma reescrita big-bang por um motivo simples: uma reescrita normalmente custa mais e demora mais, porque o sistema antigo precisa continuar rodando em paralelo de qualquer jeito. O CDC é uma das ferramentas que tornam o caminho incremental viável.

O CDC ajuda de algumas formas concretas:

  • Testes realistas: o novo sistema roda com dados frescos, com o formato de produção, e não com um dump desatualizado.
  • Migração gradual do tráfego: você pode mover uma funcionalidade ou um grupo de usuários por vez, o que combina com uma abordagem incremental em vez de uma reescrita big-bang.
  • Rollback mais fácil: enquanto o banco antigo continua atualizado, você pode mandar o tráfego de volta se algo parecer errado.

Quais são as armadilhas comuns: ordem, duplicatas e mudanças de schema?

As ferramentas são maduras. A maior parte dos problemas vem de três questões que as ferramentas não conseguem esconder por completo.

Ordem

As mudanças em uma mesma linha precisam ser aplicadas na ordem em que aconteceram. Se uma atualização do email de um usuário chega antes do insert que criou esse usuário, o destino quebra ou fica com o valor errado.

Ferramentas baseadas em log geralmente emitem as mudanças na ordem de commit, mas, se você distribui os eventos entre muitos consumidores em paralelo, pode perder essa ordem. Uma regra comum: particionar pela chave primária, para que todas as mudanças de uma linha passem pelo mesmo consumidor, em sequência.

Duplicatas

A maioria dos pipelines de CDC é projetada para entrega at-least-once. Isso significa que um evento pode chegar duas vezes depois de um restart ou de uma nova tentativa. O seu consumidor precisa ser idempotente: aplicar a mesma mudança duas vezes deve dar o mesmo resultado que aplicá-la uma vez.

Upserts pela chave primária, somados a guardar a posição no log da última mudança aplicada, são as defesas de costume.

Mudanças de schema

Alguém adiciona uma coluna, renomeia um campo ou muda um tipo na origem enquanto o pipeline está rodando. Dependendo da ferramenta, o fluxo pode quebrar, descartar o campo novo ou repassar algo que o destino não consegue interpretar.

Planeje isso de forma explícita:

  • Congele ou revise as mudanças de schema na origem durante a migração.
  • Prefira mudanças aditivas: adicione colunas novas antes de usá-las e remova as antigas só depois da virada.
  • Configure alertas para falhas e atraso no pipeline, para que uma parada silenciosa não vire surpresa na hora da virada.

Verificação

Não presuma que o destino está igual. Compare contagens de linhas, checksums das tabelas principais e verificações pontuais em registros que envolvem dinheiro, como pedidos, pagamentos e assinaturas. Rode a comparação várias vezes, não uma só.

Quando assumo um sistema, a minha ordem é: primeiro o acesso, depois o build, depois os fluxos de dinheiro, depois os riscos. Como trabalhei no time de carrinho e checkout da Total Wine & More, verifico primeiro as tabelas por trás do checkout e da cobrança, porque é ali que uma divergência silenciosa dói mais.

CDC vs escrita dupla: qual é mais seguro?

Escrita dupla significa que a sua aplicação grava no banco antigo e no novo no mesmo caminho de código. Parece simples, e é tentador quando você controla o código.

O problema é que dois bancos de dados não conseguem fazer commit de forma atômica sem um mecanismo extra. Uma escrita pode dar certo enquanto a outra falha, e aí eles divergem sem nenhum registro do motivo. Requisições concorrentes também podem aplicar mudanças nos dois bancos em ordens diferentes.

O CDC evita isso mantendo uma única fonte da verdade. A aplicação grava uma vez, e as mudanças fluem para fora a partir do log confirmado. Se o pipeline falha, ele pode retomar da última posição e se atualizar, desde que a origem ainda guarde o log de que ele precisa.

CDCEscrita dupla
Fonte da verdadeUm banco de dadosDois, que podem divergir
Mudanças no código legadoNormalmente nenhumaNecessárias em todos os caminhos de escrita
Tratamento de falhasRetoma da posição no logReconciliação customizada
Esforço de setupMaior no inícioMenor no início, maior depois

A escrita dupla pode funcionar quando o sistema é pequeno, você enxerga todos os caminhos de escrita e uma divergência breve é tolerável. Mesmo assim, eu a combinaria com um job de reconciliação. Para qualquer coisa que envolva pagamentos ou dados de usuários, eu escolheria CDC primeiro.

Quando change data capture é exagero?

O CDC adiciona peças móveis: um conector, um fluxo, consumidores e monitoramento. Alguém precisa operar tudo isso. Dispense quando:

  • O banco de dados é pequeno e uma janela de manutenção curta é aceitável.
  • Os dados mudam raramente, então uma exportação final logo antes da virada pega tudo.
  • Você só precisa de uma cópia única, não de sincronização contínua.
  • O time não tem ninguém que consiga operar e monitorar o pipeline depois do lançamento.

Uma regra prática simples, da minha própria experiência (uma estimativa, não um benchmark): se você consegue explicar todos os caminhos de escrita num quadro branco e o downtime é barato, tente primeiro a opção simples. Se os usuários gravam o tempo todo e downtime não é uma opção, o CDC compensa o custo.

Quer uma segunda opinião sobre a sua migração?

Se você está planejando uma migração e não sabe se o CDC se encaixa no seu caso, mande um email para me@filipeeduardo.dev com uma descrição curta da sua stack e do seu volume de escrita. Fico feliz em trocar ideias e dizer o que eu verificaria primeiro.

Perguntas frequentes

CDC é a mesma coisa que replicação de banco de dados?

São coisas relacionadas. A replicação nativa normalmente copia mudanças entre bancos da mesma engine. O CDC é mais geral: ele expõe as mudanças como eventos que você pode enviar para outra engine, um índice de busca ou um warehouse.

O CDC deixa o banco de origem mais lento?

O CDC baseado em log adiciona relativamente pouca carga, porque lê um log que o banco já grava. O CDC baseado em triggers adiciona trabalho a cada escrita. Em qualquer caso, teste com tráfego realista e fique de olho nas configurações de retenção de log, para que logs não lidos não encham o disco.

O CDC consegue lidar com deletes?

O CDC baseado em log consegue, já que os deletes aparecem no log. Polling por timestamp não enxerga uma linha apagada, a menos que você use soft deletes.

Por quanto tempo os dois bancos devem ficar sincronizados?

O suficiente para verificar o novo sistema e manter um caminho de rollback, e não mais que isso. Manter os dois rodando indefinidamente gera custo e confusão, então defina uma data para aposentar o antigo.

Ainda preciso de um plano de rollout com CDC?

Sim. O CDC mantém os dados alinhados, mas você ainda precisa de um jeito de rotear o tráfego gradualmente e voltar atrás, como feature flags ou uma camada de roteamento na frente dos dois sistemas. A minha regra é colocar essa chave na frente de tudo antes de escrever qualquer código novo.

change data capture

Filipe Eduardo

Engenheiro de Software Sênior. Sete anos construindo produtos web e mobile de ponta a ponta e liderando os times que os entregam.

Acompanhe

Quer conversar
sobre isso?

Trabalho com problemas assim todos os dias. Me conte o seu.

Fale comigo