Databases
ARIES Crash Recovery: Analysis, Redo, and Undo with LSN Tracking
When an IBM Db2 server loses power mid-transaction, it can restart and reconstruct the exact byte-for-byte state of a multi-gigabyte buffer pool — including the half-finished work of transactions it is about to roll back — by replaying a write-ahead log guided by a single 8-byte counter per page. That counter is the Log Sequence Number (LSN), and the algorithm is ARIES (Algorithm for Recovery and Isolation Exploiting Semantics).
ARIES is a write-ahead-logging (WAL) crash-recovery method that runs three passes over the log after a crash — Analysis, Redo, and Undo — to restore a transactional database to a consistent state in which all committed changes are durable (atomicity + durability of ACID) and all uncommitted changes are erased. It supports a steal, no-force buffer policy, fine-granularity (record-level) locking, and partial rollbacks, and it is idempotent: it recovers correctly even if the server crashes again during recovery.
- TypeWrite-ahead-logging crash-recovery algorithm
- Invented1992, Mohan, Haderle, Lindsay, Pirahesh, Schwarz (IBM Almaden), ACM TODS
- PhasesAnalysis -> Redo -> Undo (log scanned 3 times)
- Buffer policySteal + No-Force (needs both undo and redo)
- Key ideaRedo repeats history exactly, then undo losers; LSNs make replay idempotent
- Used inIBM Db2, Microsoft SQL Server, PostgreSQL (WAL), SQLite, many storage engines
Interactive visualization
Press play, or step through manually. The visualization is yours to drive — try it before reading on.
Watch the 60-second explainer
A condensed visual walkthrough — narrated, captioned, under a minute.
The Problem: Steal, No-Force, and the Durability Gap
A transactional database must guarantee atomicity (all-or-nothing) and durability (committed data survives crashes) even though it caches pages in a volatile buffer pool. Two buffer-management choices create the recovery problem:
- Steal: the buffer manager may evict (write to disk) a dirty page belonging to an uncommitted transaction. If that transaction later aborts or the system crashes, those changes must be undone on disk.
- No-Force: a transaction may commit without forcing all its dirty pages to disk. If the system crashes before those pages are flushed, the committed changes must be redone from the log.
Steal + No-Force gives the best runtime throughput (no flush-at-commit stalls, free eviction), but it means recovery needs both redo and undo. ARIES solves this with write-ahead logging: before any data page is written to disk, the log record describing that change must already be on stable storage (the WAL rule). The log is the ground truth; the on-disk data pages are merely a possibly-stale cache that ARIES reconciles after a crash.
How ARIES Works: LSNs, the Log, and Three Phases
Every log record gets a monotonically increasing Log Sequence Number (LSN). Each data page stores in its header the pageLSN — the LSN of the most recent log record whose change is reflected on that page. Comparing a log record's LSN to a page's pageLSN tells recovery, in O(1), whether a change is already present. Update records carry a prevLSN pointer, forming a per-transaction backward chain.
Two in-memory tables are rebuilt during recovery:
- Transaction Table (TT): active transactions and each one's
lastLSN. - Dirty Page Table (DPT): dirty pages and each one's
recLSN— the LSN that first dirtied that page since it was last flushed.
The three phases:
- Analysis: scan forward from the last checkpoint, rebuilding TT and DPT and finding the crash point.
- Redo (repeat history): replay every logged change — committed or not — from the smallest
recLSNin the DPT, restoring the exact pre-crash state. - Undo: roll back all transactions that were live at the crash (the losers), writing compensation records as it goes.
Complexity, CLRs, and a Worked Step-Trace
Recovery cost is O(R + U) log I/O: Redo touches every record from the oldest recLSN forward; Undo touches every record belonging to loser transactions, backward. Fuzzy checkpoints bound the redo distance, so cost is proportional to work-since-checkpoint, not database size. Normal-run overhead is one sequential log append per update — amortized O(1).
The redo step is idempotent via LSN check: apply the change only if pageLSN < recordLSN; otherwise it is already on the page. Undo emits a Compensation Log Record (CLR) for each undone action. A CLR is redo-only and stores undoNextLSN = the prevLSN of the action it just reversed. This is the crucial trick: if the system crashes mid-undo, recovery follows undoNextLSN and never re-undoes an already-compensated action — bounding total work.
LSN 10 T1 update P5 (prevLSN 0)
LSN 20 T2 update P7 (prevLSN 0)
LSN 30 T1 commit
LSN 40 T2 update P5 (prevLSN 20) <-- CRASH after this
Analysis: TT={T2:lastLSN 40}; DPT={P5:recLSN 10, P7:recLSN 20}
Redo : from LSN 10, reapply 10,20,40 where pageLSN < LSN
Undo : loser=T2. Undo 40 -> CLR undoNextLSN=20;
Undo 20 -> CLR undoNextLSN=0; done. T1 kept.
Where ARIES Runs in Real Systems
ARIES came out of IBM's DB2 development and remains the reference design for durable, high-concurrency storage engines:
- IBM Db2 and Microsoft SQL Server implement ARIES-style WAL recovery essentially as described in the paper, including CLRs and fuzzy checkpoints.
- PostgreSQL uses WAL with LSNs, full-page writes, and redo-based crash recovery driven by checkpoints; its design is ARIES-influenced though it relies on MVCC (rather than in-place undo) to hide uncommitted rows, so it has no separate on-disk undo pass.
- SQLite's WAL mode and MySQL/InnoDB's redo log + rollback segments echo the same steal/no-force + LSN discipline.
The same ideas — a monotonic sequence number, an idempotent replay log, and a checkpoint to bound replay — reappear far beyond databases: in journaling filesystems (ext4/XFS metadata journals), Kafka log offsets, Raft/Paxos replicated logs, and LSM-tree write-ahead logs (RocksDB, Cassandra). ARIES is the canonical articulation of "the log is the database."
ARIES vs. the Alternatives
The main rival at ARIES's birth was shadow paging: instead of logging, a transaction writes modified pages to new disk locations and atomically swaps a page-table root at commit. Recovery is trivial (discard uncommitted shadow pages), but shadow paging scatters logically sequential data across the disk, destroying locality, complicating concurrent access, and requiring expensive garbage collection. ARIES keeps updates in place, preserving clustering and enabling fine-granularity locking and partial rollbacks — impossible with page-granular shadowing.
Against simpler logging schemes:
- Undo-only logging needs Force (flush committed pages at commit) — heavy commit-time I/O.
- Redo-only logging needs No-Steal (pin all dirty pages of active transactions) — buffer-pool pressure.
ARIES accepts the complexity of doing both undo and redo precisely so it can run the cheapest runtime policy (Steal + No-Force). Its signature refinements over textbook undo/redo are repeating history before undo (which cleanly supports logical undo and CLRs) and physiological logging (physical-to-a-page, logical-within-a-page), which shrinks log volume while keeping replay page-local and idempotent.
Pitfalls, Failure Modes, and Significance
ARIES is subtle, and implementations fail in characteristic ways:
- WAL-rule violations: flushing a data page before its log record reaches stable storage. A crash then leaves an on-disk change with no log record to undo it — silent corruption. The log must also be flushed up to a transaction's commit LSN before reporting commit.
- Non-idempotent redo: forgetting the
pageLSN < recordLSNguard double-applies a change (e.g., increments a counter twice) if recovery restarts. - Torn / partial page writes: a crash mid-write leaves a page half-old, half-new with an unreliable
pageLSN. Systems defend with checksums plus full-page-write journaling (PostgreSQL) or double-write buffers (InnoDB). - Losing CLR
undoNextLSNchaining: re-undoing already-compensated actions, which can loop or corrupt.
Its significance is foundational: ARIES showed you can have maximal runtime concurrency and throughput and provably correct, restartable recovery at once. Thirty-plus years on, its LSN-plus-idempotent-log pattern underpins essentially every serious durable data system.
| Method | Buffer policy | Recovery cost | Tradeoff |
|---|---|---|---|
| ARIES (WAL + physiological logging) | Steal + No-Force | 3 log passes; redo from oldest recLSN, undo losers | Small runtime overhead (log I/O); fastest normal-run throughput; complex to implement |
| Shadow paging | No-Steal + Force (page copy-on-write) | Near-instant (swap page table root) | No log needed but fragments data, kills locality, poor for concurrency |
| Force / No-Steal (undo-only or redo-only) | No-Steal or Force | One phase only | Cripples runtime: forces flushes at commit or pins dirty pages until commit |
| Undo-only logging | Steal + Force | Undo losers only, no redo | Must flush all committed pages before commit -> heavy commit-time I/O |
| Redo-only logging | No-Steal + No-Force | Redo winners only, no undo | Cannot steal frames -> buffer pool must hold every dirty page of active txns |
Frequently asked questions
What do the three ARIES phases (Analysis, Redo, Undo) actually do?
Analysis scans forward from the last checkpoint to rebuild the Transaction Table and Dirty Page Table and locate where the log ends. Redo replays every logged change from the oldest recLSN in the Dirty Page Table, reconstructing the exact pre-crash page state (even for uncommitted transactions). Undo then rolls back all transactions that were still active at the crash, writing compensation log records as it reverses each action.
Why does ARIES redo the changes of transactions it is about to undo?
This is the 'repeat history' principle. By first restoring the database to its precise pre-crash state, the Undo phase can rely on a consistent starting point and use the normal prevLSN chains and logical-undo logic uniformly. It cleanly supports fine-granularity locking, partial rollbacks, and CLRs; trying to skip redo for losers would break page-LSN invariants and complicate undo enormously.
What is an LSN and how does it make recovery idempotent?
A Log Sequence Number is a monotonically increasing identifier for each log record. Each page header stores pageLSN, the LSN of the last change applied to it. During redo, ARIES applies a log record only if the page's pageLSN is less than the record's LSN; otherwise the change is already present and is skipped. This O(1) comparison makes replay idempotent, so re-running recovery after a second crash is safe.
What is a Compensation Log Record (CLR) and why is undoNextLSN critical?
A CLR is written during undo to record that an action was reversed. It is redo-only (never itself undone) and stores undoNextLSN, pointing to the next older action of that transaction still needing undo. If the system crashes mid-undo and restarts, recovery follows undoNextLSN to skip already-compensated actions. This guarantees undo work is bounded and never repeats, preventing infinite loops or double-undo corruption.
What buffer policy does ARIES assume and why does it matter?
ARIES assumes Steal plus No-Force. Steal lets the buffer manager evict dirty uncommitted pages to disk (so undo is needed); No-Force lets a transaction commit without flushing its pages (so redo is needed). This pairing gives the best runtime throughput because there are no flush-at-commit stalls and eviction is unrestricted, at the cost of needing the full redo-and-undo recovery machinery.
How does a fuzzy checkpoint speed up recovery?
A fuzzy checkpoint records the current Transaction Table and Dirty Page Table snapshot to the log without forcing dirty pages to disk, so it barely interrupts normal processing. On recovery, Analysis starts from the checkpoint and Redo starts from the smallest recLSN in the checkpoint's Dirty Page Table. This bounds the redo scan to work done since the last checkpoint rather than the entire log, keeping recovery time proportional to recent activity.