build · oxidb v0.25.21 0 entries on disk
The /dev/oxide

A build log on shipping OxiDB — notes, post-mortems, and the occasional flame war about JSON parsing, pressed straight onto an embedded engine running inside this process.

posts/0004.md · 2026-05-09

ACID hardening — atomic persist, WAL fsync, graceful shutdown

hero image for: ACID hardening — atomic persist, WAL fsync, graceful shutdown
asset · bucket: blog-images · key: 0781c2eede2ff02978561486.jpg

Durability used to be 'mostly, probably'. Now it's 'ack means on disk', verified by two crash-test harnesses.

The persist path was `fs::write` — not atomic, not durable. It got rewritten to: write a `.tmp` file, fsync its data, atomic rename onto the canonical name, fsync the parent directory. A per-collection mutex serializes concurrent commits so two writers can't both `truncate(true).open()` the same tmp file and mangle each other's bytes.

`OXIDB_LAZY_SYNC` defaulted to true. Strict mode now fsyncs every commit; the env flag is still there for benchmark configurations that explicitly want lazy. The tx-commit path used to no-op `log_wal_batch` on the B-tree backend — now durability runs through WAL fsync at commit, not a synchronous full-image persist. `sync_writes` no longer truncates the WAL inline; the truncate moved to a new `final_checkpoint` that runs at shutdown only. The old inline truncate was racy with concurrent writers and lost about three of two thousand acks under load.

Graceful shutdown: `oxidb-server` installs a SIGTERM/SIGINT handler that calls `OxiDb::shutdown` (flush + final checkpoint) before `process::exit`. SIGPIPE is ignored — otherwise a dropped client kills the worker mid-write.

Two new harnesses verify it:

tests/crash-recovery-go: 2000 inserts → SIGKILL → reopen.

Every acked write must survive.

No `.btree.tmp` leftovers.

tests/atomicity-go: Three scenarios — pre-commit

SIGKILL, post-commit SIGKILL,

mid-tx SIGTERM. Two collections

with a foreign-key link, must

recover all-or-nothing.

Both green. Multi-collection transactions actually buy you atomicity now, not just isolation hopefully.