Repository navigation
fix(catalog): abort concurrent ALTER/DROP with write-write conflict - #1489
Merged
Merged
Conversation
Concurrent ALTER TABLE statements fork from the same visible catalog version and the last committer silently drops the winner's columns (same property/column IDs, storage skew). Match createEntryNoLock and copyTableEntryForWrite: first writer wins, concurrent writers abort. Adds deterministic serial regression tests (uncommitted and committed head) and reworks ConcurrentMultiWriteAlter to use disjoint tables. Fixes #1471.
A failed statement aborts that connection's manual transaction, so ROLLBACK reports 'No active transaction'. The conflict assertions themselves passed.
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.
Fixes #1471.
Problem
Two concurrent
ALTER TABLE ADDs on the same table both commit; the loser's column is silently lost and row values shift under the surviving column (same property/column IDs forked from one base version, storage skew). Persists afterCHECKPOINT. Becomes default-reachable with #1435.Root cause:
CatalogSet::alterTableEntryanddropEntryNoLocknever calledcheckWWConflict, unlikecreateEntryNoLockandcopyTableEntryForWrite. Concurrent DDL forked from the same visible version with last-committer-wins instead of first-committer-wins.Change
src/catalog/catalog_set.cpp: WW-conflict check against the version-chain head inalterTableEntry(all alter types incl. RENAME path) anddropEntryNoLock, mirroringcopyTableEntryForWrite. Same-transaction repeated ALTER still works (head timestamp == own txn ID is not a conflict).ddl_serial_execution.test: deterministic regression tests with manual transactions across two connections — uncommitted-head ADD-vs-ADD, committed-head ADD-vs-ADD, and ALTER-vs-DROP. The loser getsCatalog exception: Write-write conflict on altering/dropping catalog entry with name t.and the winner's schema survives.ddl_concurrent_execution.test:ConcurrentMultiWriteAlterused 4 racy same-table ALTERs expecting a merge (only possible without conflict detection). Reworked to disjoint tables so it tests concurrency without asserting a lost-update merge; same-table conflicts are covered deterministically in the serial test.Testing
No local build — verification in CI (e2e
ddl_serial_executionincl. the 3 new cases; full test suite for regressions, esp. DDL/concurrency/transaction tests).