Pgmicro transaction-correctness
How WAL mechanics, checkpointing, concurrency rules, recovery work in tursodb
install
source · Clone the upstream repo
git clone https://github.com/glommer/pgmicro
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/glommer/pgmicro "$T" && mkdir -p ~/.claude/skills && cp -r "$T/.claude/skills/transaction-correctness" ~/.claude/skills/glommer-pgmicro-transaction-correctness && rm -rf "$T"
manifest:
.claude/skills/transaction-correctness/SKILL.mdsource content
Transaction Correctness Guide
Turso uses WAL (Write-Ahead Logging) mode exclusively.
Files:
.db, .db-wal (no .db-shm - Turso uses in-memory WAL index)
WAL Mechanics
Write Path
- Writer appends frames (page data) to WAL file (sequential I/O)
- COMMIT = frame with non-zero db_size in header (marks transaction end)
- Original DB unchanged until checkpoint
Read Path
- Reader acquires read mark (mxFrame = last valid commit frame)
- For each page: check WAL up to mxFrame, fall back to main DB
- Reader sees consistent snapshot at its read mark
Checkpointing
Transfers WAL content back to main DB.
WAL grows → checkpoint triggered (default: 1000 pages) → pages copied to DB → WAL reused
Checkpoint types:
- PASSIVE: Non-blocking, stops at pages needed by active readers
- FULL: Waits for readers, checkpoints everything
- RESTART: Like FULL, also resets WAL to beginning
- TRUNCATE: Like RESTART, also truncates WAL file to zero length
WAL-Index
SQLite uses a shared memory file (
-shm) for WAL index. Turso does not - it uses in-memory data structures (frame_cache hashmap, atomic read marks) since multi-process access is not supported.
Concurrency Rules
- One writer at a time
- Readers don't block writer, writer doesn't block readers
- Checkpoint must stop at pages needed by active readers
Recovery
On crash:
- First connection acquires exclusive lock
- Replays valid commits from WAL
- Releases lock, normal operation resumes
Turso Implementation
Key files:
- WAL implementation - WAL implementation
- Page management, transactions
Connection-Private vs Shared
Per-Connection (private):
- page cache, dirty pages, savepoints, commit statePager
- connection's snapshot view:WalFile
/max_frame
- frame range for this connection's snapshotmin_frame
- which read lock slot this connection holdsmax_frame_read_lock_index
- rolling checksum statelast_checksum
Shared across connections:
- global WAL state:WalFileShared
- page-to-frame index (replacesframe_cache
file).shm
/max_frame
- global WAL progressnbackfills
- read mark slots (TursoRwLock with embedded frame values)read_locks[5]
- exclusive writer lockwrite_lock
- checkpoint serializationcheckpoint_lock
- WAL file handlefile
- mainDatabaseStorage
file.db
- shared memory allocationBufferPool
Correctness Invariants
- Durability: COMMIT record must be fsynced before returning success
- Atomicity: Partial transactions never visible to readers
- Isolation: Each reader sees consistent snapshot
- No lost updates: Checkpoint can't overwrite uncommitted changes