Show HN: FBSimCity – an explorable city that shows how Firebird works

mariuz1 pts0 comments

FBSimCity — an explorable city of Firebird internals

🔥">

Control room

Scenario

— pick a scenario —<br>Steady state<br>Cache thrash<br>Stuck OIT / version bloat<br>Lock contention<br>Rush hour<br>Sweep storm<br>Nightly gbak on a busy DB<br>nbackup with delta

Query rate

Write mix

Page cache

Sweep interval

Automatic sweep

Long-running transaction<br>pins the OIT — garbage piles up

Sweep now<br>Rush hour ×60

Backup yard

gbak<br>nbackup L0<br>L1

Lock / unlock<br>Restore chain

drag to pan · scroll to zoom · click a building

← Back<br>Next →

Query trace

Auto play<br>Next step →

Keyboard & mouse

dragpan the city<br>scroll / pinchzoom<br>clickbuilding story<br>←→↑↓pan<br>+ / −zoom in / out<br>spacepause / resume the simulation<br>Tguided tour<br>Gtrace one query, step by step<br>Pdata-page anatomy<br>Dday / night theme<br>?this help<br>Escclose overlays

Anatomy of a Firebird data page

Every table lives on data pages inside the single database<br>file. Record descriptors grow from the top, record data grows from the<br>bottom, and free space sits in between — and every record carries its<br>transaction of origin plus a pointer to its previous version.

page header — type=DATA, flags, checksum/SCN, generation

dpg_sequence · dpg_relation (table id) · dpg_count (records)

descriptor[0] — offset, length

descriptor[1] — offset, length

descriptor[2] — offset, length

free space<br>(descriptors grow ↓ · records grow ↑)

rpb: txn 1042 · back version → p118/l3 · flags · format#<br>record 2 — RLE-compressed data

rpb: txn 1017 · back version → none · flags · format#<br>record 1 — RLE-compressed data

rpb: txn 998 · back version → none · flags · format#<br>record 0 — RLE-compressed data

The version chain

newest version<br>txn 1042 — what new snapshots see

↓ back pointer (delta)

older version<br>txn 981 — still visible to older snapshots

↓ back pointer (delta)

oldest version<br>below the OIT — garbage, awaiting GC / sweep

A reader walks down the chain until it finds the<br>version its transaction snapshot is allowed to see. Versions below<br>the Oldest Interesting Transaction are demolished by cooperative GC<br>or the sweep. Back versions are stored as deltas, usually on the<br>same page — this is Firebird's multi-generational architecture, and<br>why it needs no rollback segment and no WAL.

version back data sweep record page

Related Articles