Undo for Aborts
Concept. Undo reverses an aborted transaction using the old values in its log. That is undo, and it delivers atomicity: all or nothing. Undo needs the value before each change, and the log already holds it, so undo walks the transaction's log rows and writes each old value back. The hard case is a long transaction whose uncommitted changes already reached disk, and the log handles that too.
Intuition. TLong runs for hours, updating far more counters than RAM can hold, so the buffer flushes some of its 64 MB pages to disk long before it commits. Then TLong aborts. One uncommitted value is already on disk, and no old copy of the page was kept. Undo does not need one: the log holds the old value, so it writes A0 back from 22.8 to 19, and TLong leaves no trace.
A transaction aborts; undo reverses it. Redo, its mirror, replays committed work only after a crash.
How Undo Works
To abort, undo reads each of the transaction's log rows and writes the old value back to the data page. While a transaction is still running, its recent rows are cached in RAM, so the database always knows what to undo without reading disk. But undo does more than fix the page: each reversal is itself appended to the log as a W-abort row, then an abort record closes the transaction. The log now records exactly how the transaction was unwound. This logged-undo approach, where undo writes its own steps to the log as it runs, is the ARIES algorithm, from IBM.
Figure: Undo is logged: it appends W-abort rows to the logA five-column log table, Txn, Action, Var, old value, new value, built in three stages. First T1's two original writes. Then, under a note that T1 aborts, the two W-abort rows undo appends, drawn in red. Last the abort record, its value columns dashes. Color key: orange is the old value, green is the new value, red marks undo's own W-abort rows.
| Txn | Action | Var | old value | new value |
|---|---|---|---|---|
| T1 | W | A | 19 | 22.8 |
| T1 | W | B | 23 | 27.6 |
| T1 | W-abort | B | 27.6 | 23 |
| T1 | W-abort | A | 22.8 | 19 |
| T1 | abort | |||
Figure 1. T1's rows from the WAL Log page. When T1 aborts, undo does not just fix the data page, it appends its reversal to the log: a W-abort row for B (27.6 back to 23), then A (22.8 back to 19), then an abort record. The page ends at A=19, B=23. Because each reversal is itself a logged write, the log records the whole rollback, W-abort rows and all.
The Hard Case: Uncommitted Data on Disk
Undo is easy while the change is still in RAM: overwrite it. But TLong can run for hours, touching far more than RAM can hold, so its pages are flushed to disk long before it commits. That is the hard case: when TLong aborts, A0's new value 22.8 is already on disk, no old copy of the page was kept, and it must still be undone. You do not need the old page, because the log already holds A0's old value 19.
So trace the abort. The database walks the log backward, newest write first, writing each old value back as a fresh W-abort row: A1000 from 32.4 to 27, then A0 from 22.8 to 19, including the page that already flushed. A final ABORT record closes it. Because each undo is logged as its own row, the log records TLong's full rollback. TLong leaves no trace.
Figure: The log for a long transaction TLong that abortsA log table for TLong, which writes A0 and A1000 then aborts. The two forward writes raise A0 from 19 to 22.8 and A1000 from 27 to 32.4. Undo then walks the log backward, newest change first: it logs a W-abort that restores A1000 from 32.4 to 27, then a W-abort that restores A0 from 22.8 to 19, then a final abort record. The old value column drives each undo. Color key: violet is the log, red marks the undo writes that reverse the transaction, green is the restored data on disk.
| Time | Txn | Action | Var | old value | new value | disk state after |
|---|---|---|---|---|---|---|
| 13 | TLong | W | A0 | 19 | 22.8 | A0 = 22.8 |
| 92 | TLong | W | A1000 | 27 | 32.4 | A1000 = 32.4 |
| 1000 | TLong | W-abort | A1000 | 32.4 | 27 | A1000 = 27 |
| 1000 | TLong | W-abort | A0 | 22.8 | 19 | A0 = 19 |
| 1000 | TLong | abort | back to start state | |||
Figure 2. TLong aborts. Undo walks the log backward, newest write first, restoring A1000 from 32.4 to 27, then A0 from 22.8 to 19, reusing the old value each forward row recorded. Each undo becomes its own W-abort row (red), so the log records the rollback itself. A final abort record closes the transaction.
Undo gives atomicity off the log's old values, and it logs its own reversal as W-abort rows, so the log records every rollback in full. A single transaction aborts this way while the system runs. Next, a crash leaves many of them unfinished at once, and recovery replays the whole log, W-abort rows included, before undoing the losers.