Core: Preserve concurrent snapshots on replace transaction retry - #16943
Open
wombatu-kun wants to merge 2 commits into
Open
Core: Preserve concurrent snapshots on replace transaction retry#16943wombatu-kun wants to merge 2 commits into
wombatu-kun wants to merge 2 commits into
Conversation
Contributor
Author
|
@nastra @amogh-jahagirdar this one has been sitting since June 24 with no review at all. CI is green (56/56) and it still merges cleanly on current It fixes silent snapshot loss: when two Tagging you two because you handled the closest prior work in this path (#11671). A look whenever you have time would be much appreciated. |
wombatu-kun
force-pushed
the
issue/16942-replace-concurrent-snapshots
branch
from
August 11, 2026 05:46
49f6d44 to
c995464
Compare
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
wombatu-kun
force-pushed
the
issue/16942-replace-concurrent-snapshots
branch
from
September 10, 2026 04:02
c995464 to
e339dd4
Compare
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.
Closes #16942
Problem
createOrReplaceandreplacebuild their replacement metadata from the table state captured when the transaction starts, andTableMetadata.buildReplacementkeeps the existing snapshot history. When two such transactions run concurrently, the one that loses the optimistic-lock race retries inBaseTransaction.commitReplaceTransaction, but the retry advancedbaseto the refreshed metadata while re-committing the stale replacement built from the original base. As a result, any snapshot the concurrent writer committed in between was silently dropped from history. This contradicts the documented behavior that replacing a table keeps its history (docs/docs/spark-ddl.md) and is inconsistent with sequential replace, which preserves all snapshots. It affects full-metadata-rewrite catalogs (Hadoop, Hive, Glue, JDBC, Nessie, in-memory); REST already merges these changes server-side.See #16942 for the minimal reproduction.
Fix
On a replace commit retry, when a concurrent change is detected, the replacement metadata is rebuilt on top of the refreshed table and the transaction's pending updates are re-applied. The concurrent writer's snapshots stay in history while the replacement still becomes the current state, mirroring how the simple-transaction path re-applies its updates after a refresh. The rebuild is skipped when the concurrent change altered the schema or partition spec, since re-running
buildReplacementwould reassign field ids and break data this transaction already wrote; in that case the existing last-writer-wins behavior is retained. Catalogs that merge changes server-side (REST) pass no rebuild function and are unaffected.Because the replacement is now rebuilt on the refreshed base, a concurrent writer's property updates committed during a replace transaction are also preserved on retry, where the metadata-rewrite catalogs (Hadoop, Hive) previously clobbered them.
buildReplacementoverlays the replace's properties on top of the base it is built from, so a concurrently-set property that is already on the refreshed base is carried forward. This brings those catalogs in line with REST, which applies the replace as a delta and never removes a concurrently-set property server-side.Tests
Added
TestReplaceTransaction.testReplaceTransactionConcurrentCommitRetainsHistory, which forces a concurrent commit during a replace and asserts the concurrent writer's snapshot stays in history while the replacement wins the current state. It fails without the fix and passes with it across all format versions. The existing concurrent-replace coverage inCatalogTests(including the schema and partition-spec variants) continues to pass for in-memory, JDBC, and REST catalogs.TestHiveCreateReplaceTable.testReplaceTableTxnTableModifiedConcurrentlywas updated to assert that the concurrent property update is now preserved, reflecting the REST-consistent behavior described above.AI Disclosure