Skip to content

[tx] Files can join a transaction's page set after the commit lock set is computed #4937

Description

@lvca

Severity: HIGH (enabler for aborted-tx WAL replay)

Location: TransactionContext.java:644-674 (lock set computed at :652, updateRecordNoLock at :665), serializer/BinarySerializer.java:975,1166 (EXTERNAL property values written to the paired external bucket during phase-1 serialization), index/lsm/LSMTreeIndex.java:515 (during phase 1 status==COMMIT_1ST_PHASE, so indexer.updateDocument writes directly into index pages, incl. indexes created mid-tx that were absent from indexChanges at lock time), TransactionIndexContext.java:248-282 (addFilesToLock omits LSMVectorIndexs companion graph file).

Pages of these late-joining files pass phase-1 checkPageVersion without their file lock held, making the aborted-tx WAL-replay interleaving reachable and producing surprise phase-2 CMEs. Reachable with (a) EXTERNAL properties updated via the deferred path in two concurrent txns, (b) vector-index graph-file writes.

Also note deferred updates apply index mutations twice (directly at :665-673, then via putReplay at :689) - benign for lookups but doubles LSM garbage/compaction.

Fix: after updateRecordNoLock + indexChanges.commit(), assert every file in modifiedPages/newPages is locked; if not, release, re-lock the union, and re-validate (bounded retry). Add the vector graph file id in addFilesToLock.


Filed from an internal engine deep-audit (2026-07). Traced to source; verify against current main before fixing and add a regression test.

Metadata

Metadata

Assignees

Labels

auditFindings from the 2026-07 engine deep auditbugconcurrencyThreading / concurrency / MVCC

Type

Fields

No fields configured for Bug.

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions