Course contents
On this page
Restart recovery without applying a change twice
Use complete records and repeatable replay to recover a committed transfer.
The logging lesson left a committed transfer partly installed in data files. Recovery can read its log and finish the installation. But recovery is also a program: it may crash before it finishes.
We keep the same simplified model: transactions execute serially, unfinished changes never reach data pages, and storage honors the declared persistence operations. Before serving requests, recovery starts from a valid baseline and replays complete committed transactions in log order. Repairing arbitrary media corruption is a separate problem.
Make replay repeatable
Suppose the log records final values, A = 90 and B = 110. Assigning A = 90 again does not subtract another 10. An operation with the same effect when repeated is idempotent.
- Before restart
Saved A = 90, saved B = 100. T's complete commit decision is in the log.
- First recovery attempt
Set A = 90, then crash before setting B.
- Second recovery attempt
Replay from the same valid baseline and ordered log: set A = 90, then B = 110.
Blindly replaying “subtract 10” against the current value would produce A = 80 on the second attempt. An engine can use final images, sequence metadata, or other carefully designed redo rules to avoid duplicate effects. The rule must account for later transactions too; replaying an arbitrary old image after newer changes would also be wrong.
Distinguish an incomplete tail from valid history
A crash may leave a partial log record at the end. A log format needs lengths and integrity checks to identify complete records and transaction decisions. Under a defined crash model, recovery can ignore an incomplete trailing record that was never committed.
That does not mean “ignore any bytes we cannot parse.” Unexpected corruption inside required committed history must produce a controlled failure or invoke a repair procedure. Guessing could silently lose acknowledged work.
A checkpoint is a recoverable description of a state from which replay can begin. In a simple stop-the-world design, the engine can save a consistent committed baseline and record which log prefix it includes. Only after that baseline is safely published may older recovery information become unnecessary. More concurrent checkpoint schemes need additional bookkeeping.
Move the crash earlier
The log contains T’s planned values but no complete durable commit record. May recovery install those values in our private-write model?
Require evidence of the decision
No. T has not established a durable commit decision, and its tentative changes were never allowed into the data pages. Recovery leaves them out. If the model allowed unfinished writes to data pages, this answer alone would be insufficient; it would also need to remove or hide those effects.
The recovery test is not merely “the engine starts.” It is “the recovered state matches the promised transaction outcomes,” including after a second interruption.
SQLite’s atomic-commit discussion explains concrete storage assumptions and failure windows. It uses a different protocol; compare the guarantees and ordering, rather than treating our example as its implementation.
Extended reference
The extended chapter preserves the original technical coverage, additional examples, and citations. The explanation above supplies the concepts needed for this page; the reference develops the specialist cases.
Find a section from the original chapter
- Learning outcomes
- Recovery must handle a crash during recovery
- State the failure model
- Checkpoints are recovery boundaries
- Analysis, redo, and undo
- Torn pages and integrity
- Durable commit and group scheduling
- Recovery-time arithmetic
- Log retention and backup
- Recovery testing as a design method
- Work a small recovery history end to end
- Compensation records make undo restartable
- Checkpoint publication needs a valid fallback
- Torn pages require reconstructable bytes
- Calculate recovery from its resource stages
- Retention watermarks need separate owners
- A failure-injection scenario with an oracle
- Foreground speed is borrowed from recovery capability
- Visualize group commit without confusing latency and amortization
- Design conclusion
- Sources and further reading