Skip to content

fix(catalog): abort concurrent ALTER/DROP with write-write conflict - #1489

Merged
adsharma merged 2 commits into
mainfrom
fix/1471-alter-ww-conflict
Nov 2, 2026
Merged

adsharma merged 2 commits into
mainfrom
fix/1471-alter-ww-conflict

Conversation

@adsharma

@adsharma adsharma commented Nov 1, 2026

Copy link
Copy Markdown
Contributor

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 after CHECKPOINT. Becomes default-reachable with #1435.

Root cause: CatalogSet::alterTableEntry and dropEntryNoLock never called checkWWConflict, unlike createEntryNoLock and copyTableEntryForWrite. 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 in alterTableEntry (all alter types incl. RENAME path) and dropEntryNoLock, mirroring copyTableEntryForWrite. 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 gets Catalog exception: Write-write conflict on altering/dropping catalog entry with name t. and the winner's schema survives.
  • ddl_concurrent_execution.test: ConcurrentMultiWriteAlter used 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_execution incl. the 3 new cases; full test suite for regressions, esp. DDL/concurrency/transaction tests).

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.
@adsharma
adsharma merged commit 1122054 into main Nov 2, 2026
4 checks passed
@adsharma
adsharma deleted the fix/1471-alter-ww-conflict branch November 2, 2026 01:11
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: two concurrent ALTER TABLE ADDs on one table both commit, and one column is lost

1 participant