inro

Doc 3 of 5

Transactions

Written from the engine design specification. The engine is being implemented; this describes the design, not a shipped API.

One writer, lock-free readers

One writer at a time, held by an in-process mutex. Readers never block and are never blocked — a reader pins a meta page and reads the immutable tree hanging from it.

Two sync modes:

  • Sync::Commit (default): one fsync of pages and one of the meta page per commit. Maximum loss on a crash: the commit in flight.
  • Sync::Interval(d): batches syncs. Maximum loss: the commits inside the last window d. Meant for IoT, where syncing on every write wears out flash memory.

Neither mode can produce corruption, because live data is never overwritten.

Commit is the meta

Committing a transaction is writing one meta page. Everything that changed — the tree, the free list, the catalogue — is already on disk by that point; the meta write is what makes it visible.

Recovery

There is no recovery procedure to run: no WAL to replay, no log tail to scan. Opening a file costs three reads — the header and both meta pages — at constant cost regardless of whether the file is 30 KB or 2 GB. That's what makes opening five thousand databases at server startup viable.

Recovery from a crash is that same open, with one extra step: both meta slots are read, the one that fails validation is discarded, and the one with the higher valid txn_id is mounted. If a crash happened while a meta was being written, that slot is the one that fails validation, so the other one — the last meta that finished writing — is mounted instead: the commit in flight is lost, nothing is corrupted.

One detail does need attention. Pages an interrupted transaction wrote remain allocated but unreferenced from any meta — they're leaks, not corruption. They're detected at open because the surviving meta's n_pages is smaller than the file's actual size, and those pages are returned to the free list. Without this step, the file would grow a little on every crash.

No WAL, no satellite files: recovery here is a property of the two-meta-page scheme, not a separate mechanism bolted on afterward.