Pular para conteúdo

0009 — reWriteBatchedInserts=false

Status: Aprovado · Responsável: Gustavo Madruga · Atualizado em: 2026-07-06 · Decidido em: 2026-05-04

Contexto

O pipeline diff-aware (spec 003) mede quantas linhas o Postgres realmente escreveu por processamento — a métrica linhas_efetivas. O BulkUpsert usa PreparedStatement.executeBatch() com ON CONFLICT DO UPDATE WHERE IS DISTINCT FROM, e soma o int[] retornado (ignorando SUCCESS_NO_INFO) para obter esse número. A diferença enviadas - efetivas é o "churn evitado" — linhas que não mudaram e portanto não geraram evento de WAL nem checkpoint no PowerSync.

Decisão

Manter reWriteBatchedInserts=false na URL do datasource (env Coolify). Com a flag ligada, o pgjdbc reescreve N inserts individuais num único multi-VALUES e o executeBatch() passa a devolver SUCCESS_NO_INFO (-2) por posição — o que zera a granularidade per-row e mata a métrica linhas_efetivas.

Consequências

  • executeBatch() devolve o rowCount por linha → linhas_efetivas/ linhas_removidas corretas em xls_processamento (observabilidade do churn).
  • Abre-se mão da otimização de rewrite em multi-VALUES; o ganho de throughput não compensa perder a métrica que sustenta o diff-aware.
  • Divergência técnica legítima vs. o irmão Transporte: lá o bulk é COPY + TEMP TABLE, então esta flag não existe. Aqui executeBatch() é necessário justamente para o rowCount per-row — mesma filosofia diff-aware, técnica diferente por motivo real.

Alternativas consideradas

  • reWriteBatchedInserts=true (throughput): perde o per-row count e, com ele, a métrica. Descartado.
  • COPY + TEMP TABLE (como no Transporte): rápido, mas não devolve rowCount per-row — inviabiliza linhas_efetivas no modelo agregado do Onpetro. Descartado aqui.