Reading — step 1 of 3
Atomicity Through Write-Ahead Logging
Atomicity — All or Nothing via WAL
Atomicity guarantees that a transaction either completes entirely or has no effect at all. The WAL is the mechanism that makes this possible.
What Atomicity Means
A transaction with 5 operations must either:
- All 5 succeed (COMMIT) — the database reflects all changes
- None succeed (ROLLBACK or crash) — the database looks like the transaction never happened
There is no state where 3 out of 5 operations are visible. This is the "all or nothing" guarantee.
The Commit Record
The WAL provides atomicity through a simple trick: the commit record.
WAL:
LSN=1: Txn42 INSERT row A
LSN=2: Txn42 UPDATE row B
LSN=3: Txn42 DELETE row C
LSN=4: Txn42 COMMIT ← the magic moment
The COMMIT record is the single point that makes all changes durable. If the system crashes:
- Before LSN=4: No COMMIT record → UNDO all of Txn42's changes
- After LSN=4: COMMIT exists → REDO all of Txn42's changes
The Critical Window
The most dangerous moment is during the COMMIT write itself:
Writing COMMIT record to WAL:
[byte 1] [byte 2] [byte 3] ... [byte N]
↑ crash here?
If the COMMIT record is partially written (torn write), recovery can detect this through:
- Checksums: Each WAL record includes a CRC32 checksum
- Magic bytes: The commit record has a specific signature
- Length validation: Verify the record is complete
A partially written COMMIT is treated as if it doesn't exist → transaction is rolled back.
ROLLBACK Implementation
ROLLBACK uses the WAL to undo changes. Two approaches:
Approach 1: WAL-based UNDO
Read WAL records for the current transaction in reverse order
For each record, apply the "before image" (old data)
Approach 2: Shadow copy
Before BEGIN, save a copy of all data
On ROLLBACK, restore the saved copy
The shadow copy approach is simpler for in-memory databases. The WAL approach is necessary for disk-based databases.
Combining WAL + Transactions
The complete flow:
BEGIN → Mark transaction as active in WAL
INSERT/UPDATE → Write WAL record (with before + after images)
Apply change to buffer pool
COMMIT → Write COMMIT record to WAL
Fsync WAL (if synchronous mode requires it)
Mark transaction as committed
How PostgreSQL Ensures Atomicity
PostgreSQL's COMMIT writes a commit record to the WAL and updates the pg_xact (commit log) to mark the transaction as committed. The pg_xact is also WAL-logged, so crash recovery can reconstruct it.
Your Task
Combine transactions (BEGIN/COMMIT/ROLLBACK) with the WAL so that after CRASH + RECOVER, committed transactions are present and uncommitted transactions are gone.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…