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.
Severity: HIGH (enabler for aborted-tx WAL replay)
Location:
TransactionContext.java:644-674(lock set computed at:652,updateRecordNoLockat: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 1status==COMMIT_1ST_PHASE, soindexer.updateDocumentwrites directly into index pages, incl. indexes created mid-tx that were absent fromindexChangesat lock time),TransactionIndexContext.java:248-282(addFilesToLockomitsLSMVectorIndexs companion graph file).Pages of these late-joining files pass phase-1
checkPageVersionwithout 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 viaputReplayat:689) - benign for lookups but doubles LSM garbage/compaction.Fix: after
updateRecordNoLock+indexChanges.commit(), assert every file inmodifiedPages/newPagesis locked; if not, release, re-lock the union, and re-validate (bounded retry). Add the vector graph file id inaddFilesToLock.Filed from an internal engine deep-audit (2026-07). Traced to source; verify against current
mainbefore fixing and add a regression test.