Repository navigation
fix: an excluded keyless table must not block startup - #1405
Merged
Merged
Conversation
The keyless-table preflight refused to start whenever the SOURCE held a
table with no row identity, even when the operator had already excluded
that table from replication. A table the connector never reads cannot be
replicated incorrectly, so it has no business blocking startup.
The practical effect was that the only ways past a keyless table were to
add a primary key to a table you may not own, or to set
keyless.table.check.skip=true and lose the protection for every OTHER
table on the source. Neither is right when the table is already excluded.
Concretely: txnrepo uat and staging carry alembic_version in 18
databases (Alembic schema bookkeeping, 0-1 rows, no key). Excluding it is
the correct fix, but before this change the connector would still refuse
to start.
withoutExcluded() drops out-of-scope tables before the refusal decision,
honouring both Debezium list properties with Debezium semantics:
* entries are REGULAR EXPRESSIONS, full-matched against the
fully-qualified db.table -- not substring, so an exclusion written
for one table cannot silently swallow a neighbour;
* table.include.list, when set, means anything NOT listed is out of
scope.
Fails safe in the same direction as databaseFilter(): an uncompilable
pattern is IGNORED rather than treated as a match. This list can only
ever REMOVE tables from the refusal set, so a broken pattern that matched
everything would silently drop a genuinely keyless table from the check -
a false pass, which is worse than a false refusal.
Tests: KeylessTablePreflightTest 20 (5 new) - an excluded keyless table
no longer blocks (using the exact ".*.temp_.*,.*[.]alembic_version"
pattern shipped for txnrepo uat/staging, so the test fails if that
production exclusion ever stops covering the table it was written for);
exclusion is anchored not substring; a table outside table.include.list
is out of scope; no lists configured excludes nothing; a malformed
pattern is ignored while the valid entry beside it still applies.
Failing-first verified: with withoutExcluded() short-circuited, 3 of the
5 fail, each showing the excluded table still blocking.
Full suite green: 44 across KeylessTablePreflightTest,
SequenceSeedOverflowTest, SourceTsVersionAnchorTest,
DdlReplayIdempotencyTest, CreateTableNoKeySortKeyTest.
The previous commit's test run let the maven-shade-plugin regenerate dependency-reduced-pom.xml, which rewrote all 441 lines with CRLF endings and silently bumped the checked-in lombok pin from 1.18.22 to 1.18.34. Neither belongs in this change. Restored to the 2.10.0 state so the PR contains only KeylessTablePreflight.java and its test. Verified: after CRLF normalisation the only content difference between the two versions was the lombok <version> line, so nothing else is lost by reverting the file wholesale.
minguyen9988
pushed a commit
that referenced
this pull request
Aug 25, 2026
#1405 and #1406 merged upstream while this PR was open, so this branch's original base carried those same commits and the PR showed CONFLICTING. Rebuilt on the new 2.10.0 head (aa00431) by applying only this change's two files. Force-push is never used here, so the previous tip is reconciled with a -s ours merge instead. Verified byte-identical to the tested branch: the diff of both files against the 159-test-green commit is empty.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The keyless-table preflight refused to start whenever the source held a table with no row identity — even when the operator had already excluded that table from replication. A table the connector never reads cannot be replicated incorrectly, so it has no business blocking startup.
Why it matters
Before this, the only ways past a keyless table were:
keyless.table.check.skip=trueand lose the protection for every other table on the source.Neither is right when the table is already excluded.
Concretely: txnrepo uat and staging carry
alembic_versionin 18 databases — Alembic schema bookkeeping, 0–1 rows, no key. Excluding it is the correct fix, but the connector would still have refused to start.What changed
withoutExcluded()drops out-of-scope tables before the refusal decision, honouring both Debezium list properties with Debezium's own semantics:db.table— not substring, so an exclusion written for one table cannot silently swallow a neighbour;table.include.list, when set, means anything not listed is out of scope.Failing safe, in the right direction
An uncompilable pattern is ignored rather than treated as a match.
This list can only ever remove tables from the refusal set. A broken pattern treated as matching everything would silently drop a genuinely keyless table from the check — a false pass, which is strictly worse than a false refusal. Same direction as the existing
databaseFilter().Tests — 20 in this class, 5 new
".*.temp_.*,.*[.]alembic_version"pattern shipped for txnrepo uat/staging, so this test fails if that production exclusion ever stops covering the table it was written for;alembic_version_historyandxalembic_versionstill block);table.include.listis out of scope;Failing-first verified — with
withoutExcluded()short-circuited, 3 of the 5 fail, each showing the excluded table still blocking:Full suite green: 44 across
KeylessTablePreflightTest,SequenceSeedOverflowTest,SourceTsVersionAnchorTest,DdlReplayIdempotencyTest,CreateTableNoKeySortKeyTest.Where this came from
Rolling 2.10.0 onto two of our environments, the preflight refused to start: the source carries the Alembic bookkeeping table
alembic_version(0–1 rows, no key) in 18 databases. Excluding it from replication is the right answer, and we did — but the connector still would not start, because the preflight ran before the exclusion list was consulted.Base branch
2.10.0, on top ofd5cdf4fc.