O que Projetar Backfills e Replays faz?
Quando usar
- Carregar histórico para um novo modelo/pipeline.
- Reprocessar janelas passadas após corrigir um bug de transformação.
- Reproduzir eventos ou recalcular uma tabela a partir dos dados brutos.
- NÃO use para execuções incrementais normais (use
building-dbt-models/authoring-airflow-dags).
Por que merece cuidado
Backfills são a operação de rotina mais perigosa na engenharia de dados: eles
reescrevem o histórico. Feitos errado, causam dupla contagem, alteram números de ontem ou
sobrecarregam a produção. Feitos certo, são chatos e repetíveis. O pré-requisito
é idempotência (veja writing-idempotent-transformations).
Fluxo de trabalho
- [ ] Confirme que a transformação é idempotente (reexecutar == executar uma vez) ANTES de fazer backfill
- [ ] Defina a janela exata e a granularidade da partição
- [ ] Execute uma partição em modo dry-run; verifique contagens/somas versus origem
- [ ] Execute partição por partição (paralelismo limitado), não de uma vez
- [ ] Isole a computação do backfill das cargas de trabalho de produção
- [ ] Verifique totais e reconcilie; depois retome a programação normal
- Prove idempotência primeiro. Se reexecutar uma janela pode alterar resultados, corrija isso antes de tocar no histórico. Fazer backfill de um job não idempotente multiplica dados.
- Defina o escopo com precisão. Início e fim exatos e a unidade de partição (dia/hora/região).
- Execute uma partição em dry-run e reconcilie com a origem antes de escalar.
- Divida a execução em blocos. Processe partições em lotes limitados para que você possa monitorar, pausar e retomar — nunca um job gigante e ilimitado.
- Isole a computação. Use um warehouse/cluster/pool separado para que o backfill não prejudique os SLAs da produção.
- Verifique + retome. Reconcilie totais sobre o intervalo do backfill e depois devolva à programação normal.
Padrões
Backfill idempotente por partição — cada sobrescrita de partição é independente e segura para tentar novamente:
# Paralelismo limitado, um dia de cada vez; cada dia sobrescreve sua própria partição.
for day in $(seq_dates 2026-01-01 2026-01-31); do
run_transform --run-date "$day" # delete-insert / MERGE apenas para aquele dia
done
Airflow — catchup/backfill reexecuta intervalos; só é seguro quando as tasks são
idempotentes e parametrizadas pelo intervalo de dados. dbt — filtre o
modelo incremental para a janela alvo, ou use --full-refresh em uma janela limitada.
Isole + limite — warehouse/cluster dedicado e um limite de concorrência para que o backfill não degrade dashboards ao vivo.
Armadilhas comuns
- Fazer backfill de um job não idempotente — duplicatas ou totais alterados; torne-o idempotente primeiro.
- Um único job gigante e ilimitado — não é possível monitorar ou retomar, e sobrecarrega a produção; vá partição por partição.
- Compartilhar computação com produção — backfills causam picos de carga e quebram SLAs; isole.
- Sem verificação — assumir sucesso; reconcilie contagens/somas sobre o intervalo.
- Alterar a lógica no meio do backfill — histórico inconsistente; fixe a versão do código para toda a execução.
- Esquecer downstream — fazer backfill de uma tabela base sem atualizar marts/agregados dependentes os deixa inconsistentes.