Skip to content
Atomicity — All or Nothing via WAL
step 1/3

Reading — step 1 of 3

Atomicity Through Write-Ahead Logging

~2 min readTransactions & ACID

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…