CDC no SSIS: carga incremental sem varrer a tabela inteira
Como usar Change Data Capture com o CDC Control Task para transformar cargas full em cargas incrementais no SSIS — com código, o padrão de estado por LSN e quando (ou não) usar em 2026.
Em quase duas décadas cuidando de ETL, poucas dores foram tão recorrentes quanto a carga que reprocessa a tabela inteira toda madrugada. O pacote roda, relê milhões de linhas da origem, joga tudo no destino e, no fim, descobre-se que apenas algumas centenas de registros realmente mudaram. É caro para o banco transacional, lento para a janela de carga e cada vez mais frágil à medida que o volume cresce.
A resposta clássica no ecossistema SQL Server continua válida — e continua subestimada: Change Data Capture (CDC) consumido dentro do SSIS, coordenado pelo CDC Control Task. Este artigo mostra o padrão completo, com código, e discute honestamente quando ele ainda faz sentido em 2026.
A mudança de pergunta
Uma carga full pergunta: "como está a tabela agora?". Uma carga incremental pergunta: "o que mudou desde a última vez que rodei?". Toda a economia vem dessa troca de pergunta.
O CDC responde a segunda pergunta lendo o log de transações do SQL Server. Quando você habilita o CDC numa tabela, o SQL Server passa a registrar, de forma assíncrona, cada INSERT, UPDATE e DELETE numa tabela de changes espelhada (cdc.<schema>_<tabela>_CT). Seu pacote SSIS não toca mais na tabela original para descobrir o delta — ele consome esse registro de mudanças. Menos I/O na origem, menos linhas trafegando, janela de carga mais curta.
Passo 1 — Habilitar o CDC (uma vez)
O CDC é habilitado no banco e depois em cada tabela que você quer rastrear. É uma operação administrativa, feita uma única vez:
-- 1. habilita o CDC no banco
EXEC sys.sp_cdc_enable_db;
-- 2. habilita o CDC na tabela de origem
EXEC sys.sp_cdc_enable_table
@source_schema = N'dbo',
@source_name = N'Vendas',
@role_name = NULL, -- sem role de segurança extra
@supports_net_changes = 1; -- essencial p/ net changes
O parâmetro @supports_net_changes = 1 exige que a tabela tenha chave primária (ou um índice único informado) e é o que habilita a leitura de mudanças líquidas, explicada no passo 2. A partir daqui, dois jobs do SQL Server Agent passam a existir: o capture (lê o log e popula as tabelas de changes) e o cleanup (remove changes além da janela de retenção). Guarde essa informação — ela reaparece na seção de trade-offs.
Passo 2 — Ler as mudanças líquidas (Net changes)
O CDC oferece duas funções de consulta: all changes e net changes. A diferença é decisiva para data warehousing.
- All changes (
fn_cdc_get_all_changes_...) devolve cada operação ocorrida na janela. Se uma venda foi atualizada dez vezes na madrugada, você recebe dez linhas. - Net changes (
fn_cdc_get_net_changes_...) devolve o resultado líquido por chave: uma única linha com o estado final daquele registro na janela. As dez atualizações viram uma linha só.
Para alimentar dimensões e fatos, net changes é quase sempre o que você quer — menos linhas, resultado consolidado, pronto para um MERGE no destino:
-- converte os limites de tempo em LSN
DECLARE @de BINARY(10) = sys.fn_cdc_map_time_to_lsn(
'smallest greater than or equal', @data_inicio);
DECLARE @ate BINARY(10) = sys.fn_cdc_map_time_to_lsn(
'largest less than or equal', @data_fim);
-- lê 1 linha final por chave (net)
SELECT *
FROM cdc.fn_cdc_get_net_changes_Vendas(@de, @ate, 'all');
A coluna __$operation indica o tipo de mudança de cada linha (1 = delete, 2 = insert, 4 = update), o que permite direcionar cada registro para o ramo certo do seu MERGE ou do seu Conditional Split no Data Flow.
Passo 3 — O CDC Control Task e o estado por LSN
Aqui está a peça que transforma um SELECT esperto num pipeline confiável. O grande risco de qualquer carga incremental é o estado: como saber, com precisão, onde a carga anterior parou? Datas de updated_at são traiçoeiras (relógios, fusos, transações longas). O CDC resolve isso com o LSN (Log Sequence Number) — um marcador determinístico da posição no log.
O CDC Control Task do SSIS gerencia esse estado para você. O padrão de pacote tem duas instâncias dele, cercando o Data Flow:
- CDC Control Task (Get Processing Range) — no início: lê o estado salvo da última execução e calcula a janela
[último LSN processado, LSN atual]. - Data Flow — no meio: usa
CDC Source+CDC Splitterpara ler o delta e aplicar inserts/updates/deletes no destino. - CDC Control Task (Mark Processed Range) — no fim: grava o novo LSN processado numa tabela de estado (ex.:
dbo.cdc_states).
O estado costuma viver numa variável do pacote persistida nessa tabela de controle. O efeito prático é o que todo engenheiro de dados quer: idempotência. Reprocessou por engano? Rode de novo — a janela é determinística e você não duplica nem pula registros. Caiu no meio? A próxima execução retoma exatamente de onde parou.
O padrão completo do pacote
Montando as peças, o fluxo de controle de um pacote incremental fica assim:
[CDC Control Task: Get Processing Range]
|
v
[Data Flow Task]
CDC Source -> CDC Splitter
|-> Insert -> OLE DB Destination
|-> Update -> Staging + MERGE
|-> Delete -> Staging + DELETE/soft-delete
|
v
[CDC Control Task: Mark Processed Range]
Uma boa prática é não aplicar UPDATE/DELETE linha a linha no Data Flow. Direcione updates e deletes para tabelas de staging e execute um MERGE em lote no Execute SQL Task seguinte. É mais rápido e transacionalmente mais limpo do que milhares de comandos unitários.
Por que isso ainda importa em 2026
CDC no SQL Server é uma tecnologia madura, mas o problema que ela resolve não envelheceu:
- Menos I/O na origem. Ler o log em vez de varrer a tabela reduz a pressão sobre o banco transacional — que normalmente é o sistema mais sensível do parque.
- Net changes prontas para o destino. O consolidado por chave encaixa naturalmente em
MERGEde dimensões e fatos, reduzindo a lógica de deduplicação no destino. - Estado determinístico por LSN. Cargas idempotentes e reexecutáveis são a base de qualquer pipeline confiável — e o LSN entrega isso sem depender de timestamps frágeis.
Para os muitos times que ainda mantêm SSIS on-premises, essa é a forma nativa, testada e barata de aposentar o full load.
Quando NÃO usar (o lado honesto)
Nenhuma técnica é bala de prata. Antes de sair habilitando CDC em tudo:
- Retenção de log e espaço. O CDC aumenta a atividade no log de transações e mantém as tabelas de changes pela janela de retenção configurada. Dimensione o cleanup e o storage.
- Dependência do SQL Server Agent. Os jobs de capture/cleanup precisam estar rodando e monitorados. Se o Agent para, o delta atrasa.
- Cenários cloud-first. Se você está construindo algo novo no Microsoft Fabric ou num lakehouse, avalie o Copy Job do Fabric Data Factory (que já traz CDC gerenciado) ou o CDC nativo da plataforma antes de recriar o padrão on-prem. O conceito é o mesmo; a operação é mais simples.
- Origens sem log acessível. CDC lê o log do SQL Server. Para outras origens, o padrão equivalente pode ser CDC baseado em ferramenta (Debezium, conectores) ou marca d'água por coluna.
Conclusão
A pergunta que separa uma carga cara de uma carga elegante é simples: "o que mudou?" em vez de "como está tudo agora?". No SSIS, o CDC com o CDC Control Task responde essa pergunta de forma nativa, com estado determinístico por LSN e mudanças líquidas prontas para o destino. É um padrão de vinte anos que continua entregando valor — e que, bem aplicado, encurta janelas de carga, alivia o banco de origem e torna seu pipeline seguro para reexecutar.
Se você mantém alguma tabela grande em full load, comece por ela: habilite o CDC num ambiente de teste, monte o pacote com os dois Control Tasks e compare a janela de carga. Os números costumam justificar a mudança sozinhos.
Artigos relacionados
uv: o gerenciador Python que todo Data Engineer precisa conhecer
Descubra como o uv, da Astral, substituiu pip, venv e pyenv nos nossos projetos Databricks e Azure — com ganho de 10 a 100× de velocidade.
Ler artigoIngestão incremental: pare de recarregar tudo toda noite
Watermarking, change data capture e os padrões que reduzem custo e janela de processamento em pipelines de ETL.
Ler artigoGostou? Veja os e-books para conteúdo aprofundado.
E-books