8000 fix(offsets): coalesced writes report every group before an ack can throw; routing and error-category fixes (#1437 review) by minguyen9988 · Pull Request #1566 · Altinity/clickhouse-sink-connector · GitHub
[go: up one dir, main page]

Skip to content

fix(offsets): coalesced writes report every group before an ack can throw; routing and error-category fixes (#1437 review) - #1566

Merged
minguyen9988 merged 1 commit into
2.11.0from
fix-coalesced-offset-ack
Oct 10, 2026
Merged

minguyen9988 merged 1 commit into
2.11.0from
fix-coalesced-offset-ack

Conversation

@minguyen9988
Copy link
Copy Markdown
Collaborator

Addresses the review of #1437 (comment 6088266931).

High: an offset-ack failure in a coalesced write orphaned the remaining groups.

  • The bug: processBatch reported the groups of one coalesced write with one checkIfBatchCanBeCommitted call per group. That call can drain the FIFO, and the drain can throw (markBatchFinished timing out, or the FIFO consistency checks). A throw on group 1 left groups 2..N written but never recorded, so their units kept remainingGroups above zero. hasUnwrittenBatches() then stayed true, heartbeat offsets stopped, and the engine eventually stopped at handoff.wait.timeout.ms and replayed everything since the frozen offset.
  • The fix: DebeziumOffsetManagement.reportWritten(groups) marks every group first, drains once, then rethrows. If marking one group throws (for example a committer batch never registered at handoff), the remaining groups are still marked, the drain still runs, and the first failure is rethrown with any later ones attached as suppressed. Nothing is swallowed.
  • Tests, in CoalescedQueuedBatchesTest: committerFailureOnFirstOfTwoCoalescedGroupsDoesNotOrphanTheSecond (the scenario from the review) and groupThatFailsToMarkDoesNotOrphanSiblingGroups. The second fails without the fix: the sibling is never acknowledged.
  • Spec 09.01 section 3.2 is updated.

Low 1: offset-bookkeeping failures were logged as ClickHouse errors. A failure to report written rows is now wrapped in OffsetAcknowledgementException, and run() logs it as an offset acknowledgement error before the ClickHouse error classifier runs, instead of Retriable ClickHouse error (Code: -1, Category: UNKNOWN). Retry and backoff are unchanged; the next drain retries the acknowledgement. Spec 10.01 is updated.

Low 2: dotted table names shared a routing group. RoutedBatch.extractTableName and createRoutingKey now split the topic on the first two dots only, so a table named a.b gets routing key db.a.b instead of colliding with table a. Test: RoutedBatchTest.testDottedTableNameIsNotSplitFurther. Spec 03.07 is updated.

Question (PK rebuild completeness check): not a bug.

  • In PrimaryKeyBackfill.completenessCheck, the retired side INNER JOINs the key map exactly as the copy does. A row deleted at the source before the key map was loaded is therefore excluded from both the copy and the check.
  • The rebuilt side is SELECT DISTINCT over T, with no FINAL and no delete filter, so a key present in T only as a post-DDL tombstone counts as present. The method Javadoc records the measurement behind that form: with FINAL on the join, tombstoned keys were reported missing.
  • A deleted row cannot make the backfill retry forever. No change was made there.

Whole-Change-Verification: ran=JDK 17 and Maven offline. sink-connector full suite: 768 tests, 0 failures, 1 error. sink-connector-lightweight full suite: 726 tests, 0 failures, 1 error. Both errors come from a sandbox with no Docker and no network (DualJdbcDriverEndToEndIT and BinlogConnectionGuardTest.aPeerCloseOnARealSocketThrows) and occur without this change too. Targeted reruns of CoalescedQueuedBatchesTest (7), RoutedBatchTest (24) and OffsetAcknowledgementFailureTest (1) passed. Fail-without-fix check on the new mark-failure test. scripts/validate_specs.py --changed-base on 7f3102d: 83 specs, 1243 citations, PASSED; result=pass

Created on behalf of the team that co-maintains this connector; maintainers own the merge.

Generated with Claude Code (https://claude.com/claude-code)

…y acknowledgement can throw; routing and error-category fixes (PR #1437 review; Spec 09.01 section 3.2, 03.07, 10.01)

High: processBatch reported the groups of a coalesced write with one checkIfBatchCanBeCommitted call per group. That call drains the FIFO, and the drain can throw (Debezium markBatchFinished timeout, FIFO consistency checks). A throw on group 1 left groups 2..N written to ClickHouse but never recorded, so their units kept remainingGroups above zero, hasUnwrittenBatches() stayed true, heartbeats stopped committing and the engine eventually stopped at handoff.wait.timeout.ms, replaying everything since the frozen offset. DebeziumOffsetManagement.reportWritten now marks every group first (a per-group mark failure is remembered, never stops the loop), drains once, and rethrows the first failure. Tests: CoalescedQueuedBatchesTest committerFailureOnFirstOfTwoCoalescedGroupsDoesNotOrphanTheSecond and groupThatFailsToMarkDoesNotOrphanSiblingGroups (fails without the fix: the sibling is never acknowledged).

Low 1: a failure to report written rows is wrapped in OffsetAcknowledgementException and logged as an offset acknowledgement error in run(), instead of Retriable ClickHouse error (Code: -1, Category: UNKNOWN). Retry behaviour is unchanged.

Low 2: RoutedBatch.extractTableName and createRoutingKey split the topic on the first two dots only, so a table named a.b keeps its own routing group instead of sharing one with table a. Test: RoutedBatchTest.testDottedTableNameIsNotSplitFurther.

Question (PK rebuild completeness check): not a bug. The retired side joins the key map exactly as the copy does, so a row deleted at the source before the key map was loaded is excluded from both, and the rebuilt side is SELECT DISTINCT over T without FINAL or a delete filter, so a key present only as a tombstone counts as present (PrimaryKeyBackfill.completenessCheck).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@minguyen9988 minguyen9988 mentioned this pull request Oct 10, 2026
@minguyen9988
minguyen9988 merged commit 4eacfec into 2.11.0 Oct 10, 2026
14 checks passed
@minguyen9988
minguyen9988 deleted the fix-coalesced-offset-ack branch October 10, 2026 05:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

0