4.2.36Operating Systems

Journaling — why, how it works

2,063 words9 min readdifficulty · medium1 backlinks

WHY does journaling exist?

WHY is this hard? A disk only guarantees that a single sector write is atomic. It does not guarantee that several writes happen together. So a "create file" can be interrupted such that:

  • the bitmap says block 12 is used, but no inode points to it → lost block (leaked space), or
  • the directory points to an inode that was never written → dangling pointer (corruption).

The old fix (fsck): scan the entire disk after a crash to repair contradictions. Problem: time grows with disk size, not with work done before the crash. A 4 TB disk can take hours.


HOW it works — the core idea

A journal is a small dedicated circular region of the disk. The rule (called write-ahead logging):

The transaction lifecycle

  1. Begin / write descriptor — a record naming which blocks will change.
  2. Write the new data into the journal (a copy of the new block contents).
  3. Write a COMMIT block — a marker meaning "the full transaction is now safely in the journal."
  4. Checkpoint — later, copy those journal blocks to their real in-place locations.
  5. Free the journal space (advance the circular log).

WHY the commit block matters (the whole trick): the commit block is written last and is a single small write. During recovery the rule is:

Figure — Journaling — why, how it works

Modes: what do we journal?


Worked Example 1 — appending to a file, no crash

Operation: append 1 block to notes.txt. This needs to change: the data block, the inode (size + block pointer), and the bitmap.

Step Action Why this step?
1 Write descriptor "TX#7 touches inode 9, bitmap, block 50" to journal So recovery knows the scope of the transaction
2 Write new inode + bitmap (and data if data-mode) into journal Captures the intended final state durably
3 Write COMMIT for TX#7 The atomic "go" switch — now replay is allowed
4 Checkpoint: copy those blocks to real inode/bitmap locations Actually apply the change in place
5 Mark TX#7 free in the journal Reclaim circular log space

No crash → real filesystem updated correctly, journal cleaned.

Worked Example 2 — crash before commit

Crash occurs after step 2 but before step 3.

  • On reboot, recovery scans the journal, finds TX#7 with no COMMIT block.
  • Why discard? The in-place inode/bitmap were never touched (step 4 hadn't run). The on-disk filesystem is exactly as it was before the append.
  • Result: the append simply "didn't happen." Clean and consistent. ✅

Worked Example 3 — crash after commit, during checkpoint

Crash occurs during step 4 (real inode written, bitmap not yet).

  • Recovery finds TX#7 with a COMMIT block → replay: re-copy all of TX#7's journal blocks to their in-place homes.
  • Why is re-writing the already-written inode safe? Because writing the same final value twice = writing it once. That's idempotency, the property that makes WAL recovery correct.

Common Mistakes


Flashcards

What problem does journaling solve?
Crash consistency — a single logical op needs many disk writes; a crash between them corrupts the filesystem.
State the Write-Ahead Logging invariant.
The intent must be durably written to the journal before any in-place (real) structure is modified.
What single write decides whether a transaction is applied during recovery?
The COMMIT block — present ⇒ replay; absent ⇒ discard.
Why must replay be idempotent?
A crash can happen mid-checkpoint, so the same journal blocks may be copied again; rewriting the same final values must be harmless.
Why is discarding a non-committed transaction safe?
Because the in-place structures were never touched yet, so the filesystem is still in its pre-transaction valid state.
Name the three ext3/ext4 journaling modes.
journal (data), ordered (default, metadata + data-before-commit), writeback (metadata only, unordered).
Why is ordered mode safer than writeback?
It flushes data blocks before committing metadata, preventing metadata from pointing at stale/garbage data.
Does journaling guarantee durability of recent writes?
No — only consistency. Unflushed buffered writes can still be lost; use fsync() for durability.
Why is journaling faster to recover than fsck?
Recovery scales with journal size (work in flight), not total disk size.
What is "checkpointing" in journaling?
Copying committed journal blocks to their real in-place locations, then freeing that journal space.

Recall Feynman: explain to a 12-year-old

When the computer saves a file it has to change a few different things on the disk, one at a time. If it gets unplugged halfway, the file gets half-changed and broken. So before changing the real stuff, the computer first writes a little to-do list in a special notebook (the journal) and stamps it "DONE" at the very end. After a crash it reads the notebook: if a task is stamped DONE, it just redoes it neatly; if a task has no DONE stamp, it knows that task never really started, so it forgets it. That way the real files are never left half-broken.

Connections

  • File Systems — journaling is a property layered on a filesystem (ext3/ext4, NTFS, XFS).
  • Write-Ahead Logging — same technique used by Databases for ACID atomicity & durability.
  • Atomicity — the commit block provides all-or-nothing semantics.
  • fsync and Durability — distinguishes consistency from durability.
  • Copy-on-Write Filesystems — alternative crash-consistency strategy (ZFS/Btrfs) vs journaling.
  • fsck — the slower, whole-disk repair journaling replaces.

Concept Map

only single sector atomic

leaves

example

old fix

slow, scales with disk size

motivates

enforces

steps

COMMIT written last

commit present

commit missing

then

Multiple disk writes per operation

Crash-consistency problem

Inconsistent filesystem

Lost block or dangling pointer

fsck scans whole disk

Journaling

Write-Ahead Logging: journal before in-place

Transaction: descriptor, data, COMMIT

Recovery rule

Replay journal, idempotent

Discard partial txn

Checkpoint to real location

Hinglish (regional understanding)

Intuition Hinglish mein samjho

Dekho, jab tum ek file banate ho ya append karte ho, OS ko disk par kai alag-alag jagah change karni padti hai — inode, bitmap, directory entry, data block. Problem ye hai ki disk sirf ek sector ka single write atomic guarantee karti hai, saare writes ek saath hone ki nahi. Agar beech mein power chali gayi (crash), to filesystem half-updated reh jaata hai — yaani corrupt. Pehle iska solution fsck tha, jo poori disk scan karke repair karta tha, but 4 TB disk pe ye ghanton lag jaata hai.

Journaling ka core idea hai Write-Ahead Logging: pehle ek chhote se journal (scratchpad) mein likho ki "main ye-ye blocks change karne wala hoon", phir last mein ek COMMIT block likho jiska matlab hai "sab kuch journal mein safe aa gaya". Iske baad hi real (in-place) data ko touch karte hain — isko checkpoint kehte hain.

Crash ke baad recovery simple hai: journal scan karo. Agar transaction ka COMMIT mila, to use replay kar do (journal se real jagah copy). Ye safe hai kyunki same values dobara likhna harmless hai — isi ko idempotent kehte hain. Agar COMMIT nahi mila, matlab crash logging ke beech hua, to us transaction ko discard kar do — real filesystem to abhi tak chhua hi nahi tha, isliye consistent hai. Bas yahi pura trick hai.

Ek important baat yaad rakhna: journaling consistency deta hai, durability nahi. RAM buffer mein pade writes crash mein lose ho sakte hain — agar pakka chahiye to fsync() karo. Aur default ext3/ext4 mode ordered hota hai — sirf metadata journal hota hai, data ko bas commit se pehle disk pe force kiya jaata hai taaki inode kisi garbage block ko point na kare.

Go deeper — visual, from zero

Test yourself — Operating Systems

Connections