ARIES: A Transaction Recovery Method Supporting Fine-Granularity Locking and Partial Rollbacks Using Write-Ahead Logging
1992 · ACM Transactions on Database Systems · ~14 min read
Read the original paperPull the plug on a database mid-write and it must come back with every committed change and none of the uncommitted ones. ARIES is the recipe almost every database uses to do that.
The problem: fast, or safe, pick one
A database makes two promises that fight each other. A committed transaction must survive a crash: the moment the client is told “done”, the change is permanent even if the power fails a microsecond later. And an uncommitted transaction must leave no trace: if the crash comes mid-way, its half-written changes must vanish. The simple ways to keep those promises are slow. Forcing every changed page to disk at commit makes commit as slow as the disk; refusing to write any uncommitted page to disk means a big transaction cannot use the buffer pool at all.
High-performance engines want the opposite policies, which the literature calls steal and no-force: let dirty pages reach disk whenever the buffer manager likes, even before commit, and let commit return before any data page is written. Both are fine for throughput and both make recovery hard, because after a crash the disk may hold uncommitted changes that must be undone and lack committed changes that must be redone. By 1992 every vendor had a recovery scheme; most were slow, limited, or quietly wrong in corner cases. ARIES, from IBM’s Almaden lab, is the one that became the standard.
The idea: write it down first, then repeat history
The foundation is write-ahead logging. Every change is described in a log record, with the values before and after, and the record is appended to a sequential log before the page it describes may be written to disk. Commit means the log is durable up to the commit record, nothing more. The log is cheap because it is sequential, and it is complete because nothing happens that it does not describe.
How it works
Every log record has a log sequence number, and every page carries the LSN of the last record applied to it. That one field answers the question recovery asks thousands of times: has this change reached this page? If the page’s LSN is older than the record, apply it; if not, skip. Recovery runs three passes over the log.
- Analysis reads forward from the last checkpoint to find which transactions were in flight and which pages might be dirty.
- Redo reads forward and re-applies every change whose page lacks it, no matter whose transaction it was. The database is now exactly as it was at the crash.
- Undo reads backward through the loser transactions and reverses each change, writing a compensation log record for every step. A CLR records that the undo happened and points at the next record to undo, so if the system crashes during recovery, the next recovery skips the work already done instead of undoing an undo.
Run the script, flush pages to disk whenever you like (or never), then crash. Recovery must end with T1's committed write present and T2's uncommitted writes gone, whatever you did.
| lsn | txn | record | on disk |
|---|---|---|---|
| empty | |||
| page | on disk | in buffer |
|---|---|---|
| A | 10 lsn 0 | clean |
| B | 20 lsn 0 | clean |
Two rules make everything else possible. Write-ahead: a page may reach disk only after the log records describing it have. Force at commit: the log is flushed before a commit is acknowledged. Pages themselves may be flushed any time, or never.
The compensation records are the part that justifies the long title. Because undo is logged and never repeated, a transaction can be rolled back partially to a savepoint, locks can be taken on individual records rather than whole pages (two transactions may update different rows on one page, and recovery still sorts them out), and checkpoints can be taken while the system is running rather than halting everything. These were the features the vendors wanted and could not get from earlier schemes.
What it changed
ARIES is in IBM’s DB2, in Microsoft SQL Server, and in spirit in Oracle; MySQL’s InnoDB keeps separate redo and undo logs on the same principles. PostgreSQL uses write-ahead logging but skips the undo pass, because its multi-version storage never overwrites a row in place and an uncommitted row version is simply invisible. SQLite’s WAL mode is the same idea at the scale of a phone. More broadly, the paper made “the log is the truth and the pages are a cache of it” the default mental model, which the next three papers on this list each take somewhere new.
Where you meet it today
- Every database you run.
fsynclatency on the log is your commit latency; this is why the log goes on the fastest disk. - Replication. Shipping the WAL to a replica is how Postgres streaming replication and MySQL binlog replication work; the log was already the complete story.
- Change data capture. Debezium and friends read the same log to turn a database into an event stream.
- Embedded stores. RocksDB, etcd and SQLite all write a WAL before anything else; the design is the same whether the database is a cluster or a file.
The original. Read it after this page; the explainer above is a map, not a substitute.
Two lectures walk through write-ahead logging and the ARIES phases with worked examples.
How a database you probably run applies the idea.