Skip to content

[core] Validate chain partition drops against the post-commit state - #10127

Merged
JingsongLi merged 3 commits into
apache:masterfrom
LuciferYang:fix/chain-callback-postcommit-baselines
Sep 24, 2026
Merged

JingsongLi merged 3 commits into
apache:masterfrom
LuciferYang:fix/chain-callback-postcommit-baselines

Conversation

@LuciferYang

@LuciferYang LuciferYang commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

Purpose

close #10126

ChainTableCommitPreCallback rejects dropping a snapshot partition of a chain table whose delta followers would then lose their baseline (they would silently fall back to delta-only reads). Its predecessor candidates came from the pre-commit partition list, so when one commit dropped several partitions of a chain group at once (a batch INSERT OVERWRITE or a rollback), a partition dropped by that same commit still counted as the predecessor of the next one. The check passed, the commit landed, and the delta partitions lost their baseline rows.

This validates the post-commit state instead. fullyDroppedPartitions treats a partition as dropped only when the commit deletes all of its base files; a rollback deletes per-file and may leave a partition partially alive, and such a partition survives and still anchors its delta followers. Only fully dropped partitions are excluded from the candidate list and validated, so a same-commit-dropped partition can no longer masquerade as another's predecessor. Standalone drops are unaffected.

A chain-table OVERWRITE legitimately truncates a whole group's snapshot partitions: ChainTableOverwriteCommitCallback truncates the snapshot partitions that the overwrite just rewrote on the delta branch, and those partitions' surviving delta followers hold fresh, complete data that needs no baseline. The overwrite callback hands the freshly rewritten delta partitions to the pre-callback through a thread-local scoped around its synchronous truncate, and the pre-callback excludes them from the follower check. A standalone drop or rollback rewrites no delta, so a genuinely stranded follower is still rejected.

Tests

ChainTablePartitionExpireTest#testRollbackRejectedWhenBatchDroppingBaselinesOfDelta: one rollback drops both CN/20250201 and CN/20250301 of a chain group while a delta CN/20250315 follows. Pre-fix the pre-commit list let CN/20250201 serve as CN/20250301's predecessor, so the drop was accepted and the delta lost its baseline; the test asserts the rollback is now rejected and the latest snapshot is unchanged.

ChainTablePartitionExpireTest#testRollbackAllowedWhenPartitionOnlyPartiallyDeleted: a rollback that deletes only one of two files of CN/20250201, leaving it alive, while fully dropping CN/20250301, is allowed because the surviving CN/20250201 still anchors the delta. This guards against a false rejection on a partial delete.

SparkChainTableITCase#testChainTableWithMultiGroupPartition (existing) covers the whole-group INSERT OVERWRITE path that the freshly-rewritten-partition exclusion keeps working.

API and Format

no

Documentation

no

ChainTableCommitPreCallback rejects dropping a snapshot partition whose
delta followers would lose their baseline. The predecessor and successor
candidates came from the pre-commit partition list, so when one commit
dropped several partitions of a group at once (batch INSERT OVERWRITE or
a rollback), a partition dropped by that same commit still counted as
the predecessor of the next one: the check passed, the commit landed,
and the delta partitions silently fell back to delta-only reads without
their baseline rows.

Validate the post-commit state instead. A partition counts as dropped
only when the commit deletes all of its base files; a rollback deletes
per-file and may leave a partition partially alive, and such a partition
survives and still anchors its delta followers, so it is neither
excluded from the candidates nor itself re-validated. Only fully dropped
partitions are validated, and single-partition drops are unaffected.
@LuciferYang
LuciferYang marked this pull request as draft September 22, 2026 20:36
…artitions

The post-commit-state validation rejected a legitimate batch INSERT
OVERWRITE. ChainTableOverwriteCommitCallback truncates the snapshot
partitions that the overwrite just rewrote on the delta branch, and the
pre-callback saw the freshly rewritten delta followers as stranded and
threw "Snapshot partition cannot be dropped" (SparkChainTableITCase).
Those followers hold fresh, complete data and need no baseline.

Pass the freshly rewritten delta partitions from the overwrite callback
to the pre-callback via a thread-local scoped around the synchronous
truncate, and exclude them from the follower check. A standalone drop or
rollback rewrites no delta, so a genuinely stranded follower is still
rejected.
Follow-up from reviewing the freshly-written-partition handoff. Save and
restore the previous scope value instead of unconditionally clearing it,
so a future nested chain overwrite on the same thread cannot wipe an
outer scope, and return an unmodifiable view of the set from the getter.
@LuciferYang
LuciferYang marked this pull request as ready for review September 23, 2026 05:27
@JingsongLi

Copy link
Copy Markdown
Contributor

This closes a real data-integrity gap: a same-commit-dropped snapshot partition must not act as the surviving baseline for a delta follower. I traced the regular truncate path and rollback path into the pre-callback: regular OVERWRITE commits request conflict detection over changed partitions, and rollback supplies the latest snapshot’s base entries; the new fully-dropped check distinguishes whole-partition loss from a partial file delete. The overwrite scope is restored in finally, so standalone drop/rollback keeps the stricter check.

Local verification on the PR patch: all 17 ChainTablePartitionExpireTest cases passed on JDK 8, including the new reject/allow regressions. Current PR checks are green (16 successful, 2 skipped). I could not run the Spark integration suite locally because this host blocks Spark’s local socket bind; CI covers that lane.

One scale concern for production: fullyDroppedPartitions streams the entire baseFiles list for every deleted partition, adding O(deleted partitions × base files) work to a batch drop/rollback. Please group base file identities by partition once, or show a large-partition benchmark that makes this cost acceptable. The correctness fix has clear end-to-end value.

@JingsongLi
JingsongLi merged commit 157e02b into apache:master Sep 24, 2026
18 checks passed
@LuciferYang

Copy link
Copy Markdown
Contributor Author

Thank you @JingsongLi

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.

[Bug] Batch dropping multiple chain partitions in one commit silently strips a delta partition's baseline

2 participants