libdb 2026.09.3
A correctness and API-hygiene release that addresses the two highest-priority findings from a Sleepycat-engineer-voice review of the fork, plus a long-standing resource-retention issue. Every change was qualified on EC2 (Debian 12) and from a pristine clone.
Isolation: DB_TXN_SNAPSHOT restored to plain SI; new DB_TXN_SERIALIZABLE
Earlier fork releases had silently made DB_TXN_SNAPSHOT mean serializable snapshot isolation (SSI). That broke Berkeley DB's "you get exactly what you asked for" contract. This release restores the historical semantics and separates the two isolation levels cleanly:
DB_TXN_SNAPSHOT→ plain snapshot isolation (MVCC). Write skew is visible again, and such transactions are preparable — exactly as in Oracle Berkeley DB 5.3.DB_TXN_SERIALIZABLE(new flag) → serializable snapshot isolation: snapshot + rw-antidependency / dangerous-structure detection.
The SSI machinery is unchanged; it simply no longer forces itself on for plain snapshot transactions. Flag values are unchanged (DB_TXN_SNAPSHOT = 0x4) and DB_TXN_SERIALIZABLE is a new additive bit — no ABI break (sizeof(DB/DBC/DB_ENV/DB_TXN) identical). Env-level default (DB_ENV->set_flags), parent/child inheritance, and cursor auto-transactions all track the requested level.
Migration: applications that relied on this fork's SSI-by-default behavior must now pass
DB_TXN_SERIALIZABLE(or set it as the env default). PassingDB_TXN_SNAPSHOTnow yields plain snapshot isolation, which may exhibit write-skew and read-only anomalies. See the updatedtxnbeginreference and isolation guide.
Durability: os_aio async-writeback error propagation
An audit of the asynchronous-I/O buffer-writeback subsystem (across all backends) found that __memp_aio_drain silently discarded write-completion status. A failed data-page write (EIO/ENOSPC/short write) still allowed txn_checkpoint to report success and log a durable checkpoint frontier that was not actually durable — a lost update after crash recovery. The drain now propagates the first write error so a failed asynchronous write fails the checkpoint, byte-for-byte matching the synchronous path. Write-ahead logging (log-before-data) was confirmed intact. Asynchronous mpool writeback (DB_MPOOL_AIO) remains off by default.
Resource use: proactive obsolete-MVCC-version reclamation (#138)
Committed snapshot transactions that wrote could retain their MVCC version buffers — and the transaction-detail + mutex slot those buffers pin — indefinitely, because obsolete versions were reclaimed only under cache-allocation pressure. With a large cache and a wide key distribution, that pressure might never occur, so resources accumulated without bound in long-running processes. Checkpoint now proactively reclaims obsolete MVCC versions (those no active reader's snapshot can ever see), reusing the existing obsolescence test and reclamation path. In the soak workload the mutex-in-use growth went from +46.81 per 1,000 transactions to a bounded sawtooth. A reader's snapshot remains correct across reclamation (verified).
Compatibility
- On-disk, log, and shared-region formats unchanged; existing environments and databases upgrade in place.
- soname unchanged (
libdb-2026.0), public ABI is an additive-only change. - All four access methods (Btree, Hash, Queue, Recno) and the embedded/no-server model unchanged.
Known open item
The #137-family locker-slot accounting under snapshot isolation (leak_si_locker) is still present and is unchanged from prior releases; it is tracked separately and does not affect this release's changes.