From 9f0daa233a890a692d17d2678b98d374d5c22694 Mon Sep 17 00:00:00 2001 From: Greg Burd Date: Sun, 6 Sep 2026 14:02:38 -0400 Subject: [PATCH] docs(ssi): retract overclaimed serializability guarantees Outside review (#136-#140) showed the SSI docs describe the intended design, not the delivered behavior. Correct them now rather than after the fixes, so we are not shipping a promise we do not keep: - rfc/0003: drop 'the commit-time pivot check is race-free against concurrent edge recording' and 'markers are reclaimed incrementally AND BOUNDED'; add a Known-limitations section naming #136 (write skew can commit when a conflicting write lands inside DB_TXN->commit; plus the separate different-pages-of-one-btree observation), #137/#138 (reader bookkeeping not fully reclaimed -> mutex-region exhaustion), #140 (DB_LOCK_SIREAD unaccounted in the replication commit lock-list sizing). The section is removed only when each item is fixed AND covered by a test. - docs_src/api/c/txnbegin.md: add a user-facing Known-limitation note under DB_TXN_SNAPSHOT so applications do not rely on serializability alone yet. No engine change; the fixes are in flight separately. --- docs_src/api/c/txnbegin.md | 2 ++ ...003-ssi-serializable-snapshot-isolation.md | 29 +++++++++++++++++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/docs_src/api/c/txnbegin.md b/docs_src/api/c/txnbegin.md index a6fc161f6..648b7feb7 100644 --- a/docs_src/api/c/txnbegin.md +++ b/docs_src/api/c/txnbegin.md @@ -83,6 +83,8 @@ The **flags** parameter must be set to 0 or by bitwise inclusively **OR**'ing to > **Note:** In this fork, `DB_TXN_SNAPSHOT` provides *serializable* snapshot isolation. In stock Oracle Berkeley DB, `DB_TXN_SNAPSHOT` provided only plain (non-serializable) snapshot isolation, and the earlier `DB_TXN_SNAPSHOT_SAFE` flag has been removed — there is no separate non-serializable snapshot mode. + > **Known limitation (as of 5.3.34).** Outside review found that the serializable guarantee is **not yet absolute**. A conflicting write that lands while another transaction is *inside* DB_TXN->commit() can escape detection, allowing a write skew to commit; and two records on different pages of one B-tree may not be detected as conflicting. Separately, long-lived environments running many snapshot transactions can exhaust the mutex region (`ENOMEM`) because reader bookkeeping is not fully reclaimed. Applications that depend on serializability for a correctness invariant should not yet rely on it alone. Tracking: issues #136, #137, #138 (and #140 for a related replication-path defect). + - `DB_TXN_SYNC` Synchronously flush the log when this transaction commits or prepares. This means the transaction will exhibit all of the ACID (atomicity, consistency, isolation, and durability) properties. diff --git a/rfc/0003-ssi-serializable-snapshot-isolation.md b/rfc/0003-ssi-serializable-snapshot-isolation.md index 19b50ad56..44ef3652f 100644 --- a/rfc/0003-ssi-serializable-snapshot-isolation.md +++ b/rfc/0003-ssi-serializable-snapshot-isolation.md @@ -58,9 +58,32 @@ Both of Cahill's rw-conflict detection paths are implemented: 2. **MVCC version-chain path** in `mp_fget` — a reader handed an older version than one a concurrent writer committed. -SIREAD markers are reclaimed incrementally and bounded (not only at -checkpoint); the commit-time pivot check is race-free against concurrent edge -recording. The two working notes in `rfc/0003/` are the porting/design record: +SIREAD markers are reclaimed incrementally (not only at checkpoint). + +> **Known limitations (2026-09, from external reports #136–#140).** The claims in +> this RFC describe the *intended* design; the delivered behavior is weaker in +> ways confirmed by outside review. Until the fixes land with regression tests, +> treat the serializability guarantee as **best-effort, not absolute**: +> +> - **#136 — write skew can commit.** The commit-time pivot check is **not** +> atomic with respect to the `TXN_RUNNING` → `TXN_COMMITTED` transition. A +> conflicting write that lands while the first transaction is *inside* +> `DB_TXN->commit` can leave both transactions committing, producing a state +> with no serial order. A separate observation from the same report: two +> records on *different pages of one B-tree* may detect no conflict at all. +> (An earlier working note in this directory claimed this race was resolved; +> that claim was wrong and is retracted.) +> - **#137 / #138 — marker reclamation is not fully bounded.** SIREAD cleanup +> does not reclaim the deferred committed-reader locker, and +> `__txn_reap_si_details` frees a transaction detail without releasing its MVCC +> mutex. Long-lived environments running many snapshot transactions can +> therefore exhaust the mutex region and see `ENOMEM`. +> - **#140 — lock-list sizing.** `DB_LOCK_SIREAD` was not accounted for in the +> replication commit lock-list sizing (a heap overflow in release builds). +> +> This section is removed only when each item is fixed *and* covered by a test. + +The two working notes in `rfc/0003/` are the porting/design record: - **`M2-partition-design.md`** — porting Cahill's 4.6.21 single-global-lock-table SIREAD GC onto 5.3.x's *partitioned* lock regions (`OBJECT_LOCK_NDX` is now