WAL — durability without rewriting the file every commit
Commits append a page-image frame to the WAL and fsync it; the main DB file is left alone until checkpoint, so commits are sequential appends and readers don't block writers.
The page cache made reads RAM-fast and let writes happen in cache. But a crash erases RAM — the engine still owes you a story for how a commit becomes durable without rewriting random pages of the main file every time.
Scene 08
WAL — durability without rewriting the file every commit
- Watch
- Try it
- Predict
- Capture
Watch one COMMIT walk the four steps. Mutate the page in cache, append a frame to the WAL, fsync the WAL, then return. The DB file is not touched.
Highlighted lines are the ones running in the diagram right now.
def commit(txn):for page in txn.dirty_pages: # step 1: in cachewal.append(Frame(page.id, page.bytes))wal.append(Frame(commit=True)) # commit markerif synchronous in (FULL, EXTRA):fsync(wal) # step 3: durableshm.update_index(txn.dirty_pages) # readers see latestreturn OK # step 4# NOTE: db file is NOT touched here
def read_page(page_id, snapshot_end_mark):# check shm for latest frame ≤ end_markframe = shm.lookup(page_id, snapshot_end_mark)if frame is not None:return wal.read(frame) # served from WALreturn db_file.read(page_id) # fall back to main file
def commit_rollback(txn):journal.write(originals(txn.dirty_pages))fsync(journal) # 1st fsyncdb_file.write(txn.dirty_pages) # rewrite the FILEfsync(db_file) # 2nd fsyncdelete(journal) # commit point# readers were blocked under EXCLUSIVE this whole time
Where this sits in Build a B-tree storage engine (SQLite-style)
Scene 08 of 11, in the Speed & durability act — Page cache, WAL+fsync, and the checkpoint that keeps WAL bounded.. Commits append page-images to the WAL and fsync; the main DB file is left alone until checkpoint — fast, and readers don't block.
Up next. The WAL grows by one frame on every commit. Eventually that has to be cleaned up — that's checkpointing — and there is one canonical way it goes wrong: a long-lived reader pins the WAL open and it grows without bound.
All 11 scenes in Build a B-tree storage engine (SQLite-style) · Every curriculum