Lesson 0007 · Internals & Performance

Durability: redo & undo logs

Why a COMMIT survives a power cut even though your changed rows are still sitting in memory — the write-ahead log, and the undo log that also powers rollback and MVCC.

~11 minRetrieval quiz + hands-on inspectionCheat sheet: here

You've covered how MySQL reads fast (0001–0004) and stays correct under concurrency (0005–0006). The last core pillar is the D in ACID — durability: once COMMIT returns, that change must survive a crash. The puzzle: InnoDB doesn't write your changed data pages to disk at commit time. So how does a committed change come back after a power cut? The answer is two logs.

The one idea: write-ahead logging

WAL — the keystone

Before a change is applied to the data files, InnoDB first records it in the redo log — a small, sequential append on disk — and only that log write must be durable at COMMIT. The actual data pages are updated in the in-memory buffer pool and flushed to disk later. This is write-ahead logging: log first, pages later. A sequential log append is far cheaper than scattering random page writes across the disk, which is why COMMIT is fast and durable at the same time.

The two logs do opposite jobs

LogAnswers the questionUsed for
redo log"How do I re-apply a committed change I hadn't flushed yet?"Crash recovery (roll forward)
undo log"How do I reverse a change?"ROLLBACK & MVCC (roll back)

Redo — roll forward after a crash

The redo log is a disk structure used during crash recovery to fix data from incomplete work: modifications that didn't finish reaching the data files before an unexpected shutdown are replayed automatically on startup, before connections are accepted. MySQL Manual: "The redo log is a disk-based data structure used during crash recovery to correct data written by incomplete transactions… replayed automatically during initialization."

Undo — reverse a change (and rebuild old versions)

An undo log record holds how to undo the latest change a transaction made to a clustered-index record — that's what ROLLBACK uses. But it does double duty: it's also where MVCC gets earlier row versions for the consistent snapshot reads you met in Lesson 0005. MySQL Manual: "An undo log record contains information about how to undo the latest change by a transaction… If another transaction needs to see the original data as part of a consistent read operation, the unmodified data is retrieved from undo log records."

The whole picture in one line

redo = repeat committed work you might lose on a crash; undo = take back uncommitted work (and remember what rows used to look like for MVCC). Redo protects the committed; undo protects the not-yet-committed and the readers.

The durability dial: innodb_flush_log_at_trx_commit

How hard the redo log is pushed to disk at each commit is tunable — the classic durability-vs-throughput trade-off:

ValueAt each COMMITCrash risk
1 (default)Redo written and flushed (fsync) to disk.None — full ACID.
2Redo written to OS cache; fsync'd ~once/second.Lose ≤ ~1s only on OS/power crash (a mysqld-only crash is safe).
0Redo written + fsync'd ~once/second, not at commit.Lose ≤ ~1s even on a mysqld crash.

MySQL Manual: "The default setting of 1 is required for full ACID compliance… logs are written and flushed to disk at each transaction commit." Values 0 and 2 flush ~once per second and can lose unflushed transactions in a crash.

Interview-grade nuance: 1 vs 2

The difference between 1 and 2 is who has to survive. Value 2 hands the redo to the OS at commit, so if only MySQL crashes (process dies) nothing is lost — the OS still flushes it. You only lose the last ≤1s if the whole machine loses power. That makes 2 a popular "fast but mostly safe" choice; 1 is the only fully-ACID setting.

Check yourself

Answer from memory — effortful recall is what builds retention. Feedback is immediate.

The redo log is used primarily for:

The redo log rolls committed-but-unflushed changes forward on restart. Reversing changes is the undo log's job.

Besides ROLLBACK, the undo log also powers:

Undo records hold prior row versions, so consistent snapshot reads (Lesson 0005) reconstruct old data from the undo log. Double duty: rollback + MVCC.

Write-ahead logging means a change is durable in the:

WAL writes the change to the sequential redo log first; the data pages are updated in the buffer pool and flushed later. Log first, pages later.

With innodb_flush_log_at_trx_commit = 1, the redo log is flushed:

Value 1 (the default) writes and fsyncs the redo log at every commit — the only fully ACID-durable setting.

Setting the dial to 2 risks losing a committed transaction on:

Value 2 hands redo to the OS cache at commit and fsyncs ~1s later, so only a full OS/power crash can lose the last ≤1s. A mysqld-only crash is safe.

COMMIT is fast despite unflushed data pages because it does a:

A commit only needs the small, sequential redo append to be durable — far cheaper than scattering random data-page writes across the disk.

A modified page still in the buffer pool, not yet flushed, is a:

A "dirty" page holds changes not yet written to the data files. The redo log makes that safe: even if a dirty page is lost in a crash, its change is replayable from redo.

Hands-on: inspect the durability machinery

You can't easily crash MySQL safely, but you can watch the logs work.

1 · Your durability setting

SHOW VARIABLES LIKE 'innodb_flush_log_at_trx_commit';   -- 1 = full ACID

2 · Watch the redo log advance (the LSN)

SHOW ENGINE INNODB STATUS\G
-- In the LOG section: "Log sequence number" (LSN) climbs as you write;
-- "Log flushed up to" and "Last checkpoint at" trail behind it.

-- Do some writes, then re-run and watch the LSN move:
UPDATE people SET city = CONCAT(city, '!') WHERE id = 1;
SHOW ENGINE INNODB STATUS\G   -- LSN is now higher

3 · See undo in action — a rollback

START TRANSACTION;
UPDATE people SET city = 'GONE' WHERE id = 1;
SELECT city FROM people WHERE id = 1;   -- 'GONE' (your own change)
ROLLBACK;
SELECT city FROM people WHERE id = 1;   -- restored — undo log reversed it
What you should observe

The LSN (log sequence number) is the redo log's ever-growing byte counter — every change advances it, and "flushed up to" shows how much is safely on disk. The ROLLBACK silently restores the old value straight from the undo log — the same machinery that would have served that old value to a concurrent snapshot read (0005). Bring me a SHOW ENGINE INNODB STATUS LOG section and we'll read the LSN/checkpoint story.

Primary source — read this next

MySQL 8.0 Reference Manual — Redo Log and Undo Logs, then Optimizing InnoDB Transaction Management for the innodb_flush_log_at_trx_commit trade-off in context.