Contrato da fonte
A fronteira da extração, o perfil da origem e a semântica de atualização.
Contrato da fonte, estratégias de captura e idempotência, com a construção de uma extração incremental sobre uma origem transacional que sofre atualização e exclusão.
Computação 2 · Prof. Hermano Peixoto · 09/09/2026
Continuidade · da Aula 10 para a Aula 12
A Aula 10 decidiu onde e como o dado fica guardado. Esta aula trata de como ele entra, com que garantias e sob qual possibilidade de reprocessamento.
Roteiro · 120 minutos · uma hora de exposição, uma hora de prática
A segunda hora é atividade em grupo: extrair de uma origem transacional que sofre atualização e exclusão, e medir o que cada estratégia perde.
A fronteira da extração, o perfil da origem e a semântica de atualização.
Full load, incremental por watermark, CDC e idempotência.
Paginação, retry, chegada atômica, controle e replay.
Extração incremental sobre Postgres, com mutações deliberadas que produzem divergência.
Bloco 1 · A fronteira
Antes dessa fronteira, o dado obedece às regras de quem o produz. Depois dela, a responsabilidade pela completude e pela rastreabilidade é do pipeline.
O sistema transacional otimiza a escrita e o atendimento ao usuário. A leitura analítica compete por recurso, e a origem pode limitar, atrasar ou recusar a extração sem aviso. A janela de disponibilidade integra o contrato.
A extração que termina sem erro pode ter trazido metade dos registros. A verificação se faz por contagem reconciliada com a origem.
Bloco 1 · Perfil da fonte
Nove atributos determinam a estratégia de extração. O levantamento posterior à implementação tende a exigir a reescrita do pipeline.
Responsável pela origem e canal de comunicação em caso de mudança.
Chave natural que identifica o registro de forma estável ao longo do tempo.
Semântica de atualização: a origem corrige a linha, ou insere uma nova?
Exclusão física ou lógica, e como ela é observável de fora.
Timezone dos carimbos de tempo e se há horário de verão na série.
Janela de disponibilidade: quando a origem aceita carga de leitura.
Limites de requisição, de volume por página e de tempo de conexão.
Campos sensíveis, classificados antes da primeira extração.
Volume e crescimento, que determinam se o full load continua viável.
Bloco 1 · Semântica de atualização
A origem pode apresentar três comportamentos, cada um com consequência distinta para a estratégia de extração.
Cada fato gera uma linha nova, e a correção entra como novo registro. É o caso mais simples: o incremental por carimbo de criação captura todas as inserções, desde que a janela tenha sobreposição para registros de visibilidade tardia.
Estratégia: incremental por timestamp de criação.
O registro muda de estado sem mudar de identidade. A captura depende de um campo de atualização que a origem mantenha de forma disciplinada em toda escrita.
Estratégia: incremental por timestamp de atualização, com verificação periódica.
O registro desaparece sem deixar rastro consultável. Nenhuma consulta ao estado atual revela o que existia antes, porque não há o que ler.
Estratégia: captura pelo log de transações, ou reconciliação periódica de chaves.
Bloco 1 · Tipos de origem
O que se negocia com quem mantém a origem, e como a extração degrada quando o contrato não é cumprido.
| Origem | O que precisa ser negociado | Modo de falha característico | Defesa correspondente |
|---|---|---|---|
| Banco relacional | Réplica de leitura, janela e acesso ao log | A consulta analítica concorre com a transação e é interrompida | Extrair da réplica, em janela acordada e com lote limitado |
| API | Limite de requisições, paginação e contagem declarada | HTTP 429 sem espera, ou página vazia com status 200 interpretada como fim | Respeitar Retry-After, aplicar retry com backoff e validar pela contagem declarada |
| Arquivo | Convenção de nome, checksum e sinal de conclusão | Leitura do arquivo enquanto ele ainda está sendo gravado | Separar landing de processamento e mover após o checksum |
| Evento | Schema registrado, retenção e garantia de entrega | Reentrega do mesmo evento após falha parcial | Ingestão idempotente por chave natural e janela |
Bloco 2 · Estratégias de extração
O volume determina o custo e a semântica de atualização determina a corretude; entre as estratégias corretas, escolhe-se a de menor custo.
custo alto · corretude alta
custo baixo · corretude condicional
custo médio · corretude alta
Bloco 2 · Watermark
É um valor persistido, avançado apenas quando o lote inteiro conclui. A janela seguinte parte dele, com sobreposição deliberada.
O evento gravado na origem no instante da virada da janela pode não estar visível quando a extração lê. A sobreposição de alguns minutos recupera esse registro, e a deduplicação por chave natural remove a repetição resultante.
Avançar a marca antes de a gravação concluir cria uma lacuna permanente: a janela seguinte parte de um ponto cujo conteúdo nunca foi persistido, e nenhuma execução posterior o alcança.
Bloco 2 · Divergência
As três produzem destino incorreto sem emitir erro, o que dificulta sua detecção em produção.
| Evento na origem | O que a extração observa | Efeito no destino | Correção |
|---|---|---|---|
| Exclusão física | A linha desaparece, sem alteração de carimbo | O registro permanece no destino indefinidamente | Captura pelo log, ou reconciliação de chaves por anti-junção |
| Atualização sem carimbo | Nada, porque o campo de controle não se moveu | O destino guarda o valor anterior como se fosse o vigente | Gatilho na origem, ou reconciliação periódica por full load |
| Escrita retroativa | Um registro com carimbo anterior à marca d'água | O registro nunca entra, porque a janela já passou daquele ponto | Filtrar pelo campo de atualização mantido pela origem, com sobreposição, e reconciliar periodicamente |
Bloco 2 · Captura pelo log
O banco já grava cada escrita em um log para garantir durabilidade e recuperação. A captura de mudanças lê esse mesmo log.
Confirme a retenção do log na origem: ela define a janela máxima de replay.
Garanta ordenação por chave: as operações do mesmo registro precisam chegar em ordem.
Trate o consumo como ao menos uma vez e torne a aplicação idempotente.
Planeje a carga inicial: o log registra as alterações posteriores ao início da captura, e o acervo anterior exige instantâneo.
Negocie o acesso privilegiado: a leitura do log exige permissão que o DBA controla.
Monitore o atraso de consumo: no PostgreSQL, o slot de replicação retém o WAL não consumido e pode esgotar o disco da origem; em logs com retenção fixa, o trecho expirado gera lacuna.
Bloco 2 · Idempotência
A idempotência torna o replay seguro e permite corrigir falhas parciais por reexecução.
A chave identifica o registro, a ordenação decide qual versão prevalece e a regra de desempate resolve o empate de forma determinística. Sem os três declarados, duas execuções da mesma janela produzem resultados distintos.
Cada execução recebe um identificador, e o registro guarda de qual lote veio. O reprocessamento se torna uma operação declarada, com efeito conhecido antes de ser executada.
Bloco 3 · APIs
O status 200 indica que a requisição foi atendida e não informa quantos registros eram esperados.
Encerre a paginação pela contagem total declarada ou pelo cursor de continuação. Algumas APIs sinalizam o limite de requisições com página vazia e status 200, caso que a extração precisa detectar.
O limite é sinalizado por HTTP 429 (Too Many Requests), em geral com o cabeçalho Retry-After. Repetem-se apenas erros transitórios (429 e 5xx), com intervalo crescente e variação aleatória, respeitando o Retry-After.
Grave a resposta como veio, antes de qualquer conversão. Quando o formato mudar ou a interpretação se revelar errada, o reprocessamento parte do original em vez de exigir nova extração.
Bloco 3 · Arquivos
A chegada de um arquivo é um processo com duração, e a leitura durante esse intervalo produz carga parcial que se apresenta como bem-sucedida.
Separe landing de processamento, e mova o arquivo apenas após verificar o checksum.
Exija sinal de conclusão: arquivo auxiliar ou renomeação atômica ao terminar a gravação.
Valide encoding, delimitador e schema antes de processar, e rejeite com motivo registrado.
Detecte reenvio pelo checksum: o mesmo arquivo entregue duas vezes não deve duplicar o destino.
Trate coluna nova como evento de governança, com decisão registrada e não como falha.
Uma coluna acrescentada, renomeada ou reordenada altera a interpretação de todo o arquivo. Na leitura posicional, o valor de uma coluna passa a ser lido como se fosse de outra, e a carga conclui sem erro.
Defesa: leitura por nome de coluna, validação do schema contra o contrato registrado e alerta quando a diferença aparece.
Bloco 3 · Operação
A tabela de controle transforma a extração em operação auditável, com estado consultável e replay previsível.
Segunda hora · Card de trabalho em sala
Em grupo, sobre a origem montada em sala: extrair os pedidos, aplicar mutações deliberadas na origem e medir o que cada estratégia deixou de capturar.
Compare o destino do incremental com o de um full load posterior às mutações. A diferença deve ser quantificada e explicada.
Identifique por anti-junção as chaves do destino ausentes na origem e some a receita afetada a partir de order_payments.
Execute a mesma janela duas vezes e compare contagem e soma de verificação. A carga é idempotente quando ambas coincidem.
Segunda hora · Arquitetura
O lakehouse da Aula 10 permanece como destino. O que se acrescenta é uma origem viva, que sofre inserção, atualização e exclusão durante o encontro.
O arquivo CSV é imutável e não permite observar o que acontece quando a origem corrige e apaga registros. O banco transacional torna a divergência reproduzível e mensurável em sala.
O bucket, a convenção de prefixo e o formato Parquet permanecem. A aula acrescenta a tabela bronze.pedido, a camada de controle e o carimbo de lote, sem refazer o ambiente.
Segunda hora · Preparação · 10 minutos
Um container, a credencial do MinIO recriada na sessão e as tabelas do destino.
Segunda hora · Full load · 10 minutos
Executada uma vez, antes de qualquer mutação, ela define o estado correto contra o qual as estratégias seguintes serão medidas.
Segunda hora · Incremental · 15 minutos
Cada grupo implementa a janela, a sobreposição e o avanço condicionado da marca d'água.
Segunda hora · Mutações · 15 minutos
Execute o bloco no DuckDB, que o aplica à origem anexada, e rode o incremental de novo. Os três conjuntos de pedidos são disjuntos.
O carimbo se moveu e a janela alcança as linhas.
O carimbo não se moveu, e a extração não percebe a mudança.
A linha não existe mais na origem para ser lida.
Segunda hora · Reconciliação e replay · 10 minutos
Sem acesso ao log de transações, a defesa disponível é comparar periodicamente o conjunto de chaves da origem com o do destino.
Marcar a exclusão preserva o histórico e permite responder desde quando o pedido deixou de existir. Remover a linha alinha o destino ao estado atual e apaga a informação. A escolha cabe à área de negócio e deve ser registrada.
A comparação de chaves tem custo próximo ao do full load e, por isso, é executada periodicamente. A frequência se define pela tolerância a divergência declarada no requisito não funcional.
Segunda hora · Replay
A verificação encerra o laboratório e demonstra que a extração pode ser reprocessada sem intervenção manual.
Segunda hora · Conferência
Números esperados em cada etapa, sobre a tabela de pedidos da Olist com as mutações aplicadas na ordem A, B e C.
| Etapa | O que verificar | Referência |
|---|---|---|
| Origem carregada | Contagem na tabela do Postgres | 99 441 pedidos, idênticos ao CSV |
| Full load | Contagem gravada em bronze.pedido | 99 441, com um único batch_id |
| Após as mutações | Contagem na origem | 99 241, com 200 excluídos fisicamente |
| Incremental | Linhas trazidas pela janela | 501: os 500 do caso A e uma linha da sobreposição |
| Reconciliação | Anti-junção e comparação de estado | 200 chaves ausentes e 300 estados divergentes |
| Receita afetada | Pagamentos dos pedidos excluídos ou divergentes | 500 pedidos, R$ 76 317,52 |
| Replay | Contagem e soma de verificação antes e depois | Idênticas, com dois lotes na tabela de controle |
Segunda hora · Uso de IA · em paralelo
O assistente acelera a escrita do SQL e do controle. A conferência dos números permanece atribuição do grupo e determina a correção do resultado.
"Este é o schema da tabela de pedidos. Liste as perguntas que preciso responder sobre a origem antes de escolher entre full load, incremental por carimbo e captura pelo log."
"Escreva SQL DuckDB que extraia do Postgres anexado apenas o que mudou desde a última marca d'água, com sobreposição de cinco minutos, aplicação idempotente e registro em tabela de controle."
"Aponte, neste pipeline, o que se perde quando a origem apaga uma linha, o que acontece se a execução falhar depois de gravar metade e o que quebra se a mesma janela rodar duas vezes."
Confira a contagem em cada etapa e explique cada diferença antes de seguir.
Verifique se o SQL gerado avança a marca d'água antes ou depois da gravação.
Registre o prompt junto do SQL, uma vez que ele integra o registro da decisão.
Segunda hora · Medição
Cada evidência corresponde a um valor obtido por execução.
| Evidência | Como obter | O que ela demonstra |
|---|---|---|
| Custo de cada estratégia | Tempo e linhas lidas do full load contra o incremental | Quanto a janela economiza em leitura da origem |
| Divergência acumulada | Anti-junção entre destino e origem após as mutações | Que a perda é silenciosa e cumulativa |
| Efeito no negócio | Soma de payment_value (order_payments) dos pedidos excluídos ou divergentes | Que a divergência técnica altera o número apresentado |
| Idempotência | Contagem antes e depois do replay da mesma janela | Que a reentrega não duplica o dado |
| Auditoria | Linhas em ctl.extracao ao final do encontro | Que cada execução é rastreável e reproduzível |
Ponte com a Aula 1 · Spec-Driven Development
A decisão de extração entra no projeto como requisito, decisão registrada e critério verificável.
Ingerir todas as alterações de pedidos da origem, inclusive exclusões e correções retroativas.
Atraso da marca d'água menor ou igual a uma hora; taxa de rejeição até 0,1%; qualquer janela dos últimos 30 dias reprocessável sem intervenção manual.
Captura pelo log de transações em vez de incremental por campo de atualização. Contexto: a origem apaga registros e corrige lançamentos com data retroativa. Consequência: exige retenção do log e garantia de ordenação.
Dado que o lote de 09/09/2026 já foi carregado, quando reprocesso o mesmo identificador de lote, então o volume no destino permanece igual e a auditoria registra duas execuções.
Entrega do card de trabalho
O que o grupo entrega ao final da segunda hora, e o que será conferido.
O SQL da carga inicial, da janela incremental e da reconciliação; os três números medidos e a receita afetada; e uma frase por número que declare o efeito sobre a decisão de negócio do parceiro.
A origem transacional está no ar e a contagem inicial coincide com a do CSV.
A tabela de controle registra cada execução com lote, janela, marca d'água e status.
A marca d'água avança somente após a gravação do lote concluir.
Os três casos de mutação foram aplicados, e a divergência está medida em contagem e em receita.
O replay da mesma janela mantém contagem e soma de verificação e registra duas execuções distintas.
A decisão sobre exclusão marcada ou removida está declarada por escrito.
Autoestudos · antes do próximo encontro
O que a origem precisa garantir para que a extração seja correta, e o que fazer quando ela não garante?
Leia a visão geral identificando o que a captura pelo log exige da origem, e compare com o que a origem do parceiro do projeto oferece hoje.
debezium.io · documentação LeituraObserve como o capítulo trata recusa de carga e recuo exponencial, e traduza as recomendações para a extração de uma API com limite de requisições.
sre.google · capítulo DocumentaçãoPercorra a documentação da extensão usada no laboratório, com atenção ao que é lido sob demanda e ao que é materializado no motor.
duckdb.org · documentaçãoAula 12 · Síntese
Coleta e Extração · 09/09/2026 · Prof. Hermano
Levantar o contrato de uma fonte, escolher entre full load, incremental por carimbo de tempo e captura pelo log a partir da semântica de atualização da origem, e construir uma extração idempotente cuja divergência seja medida e explicada.
Primeira hora de exposição dialogada em três blocos, cada um encerrado por checklist de aplicação e erro comum. Segunda hora de atividade em grupo: os estudantes montam uma origem transacional em Postgres com os pedidos da Olist, extraem por full load e por janela incremental para o lakehouse da Aula 10, aplicam mutações deliberadas de atualização e exclusão na origem e medem exatamente o que cada estratégia deixou de capturar.