2026-10-26·by Sijie Wang#fundamentals#storage#wal#durability

wal

WAL:日志先行,所以提交可以又便宜又丢不了

它是干嘛的。 改动在内存里做,快;数据页落盘慢,还是随机写(一会儿这页一会儿那页)。但事务一提交就必须丢不了——断电、进程崩溃都不行。这个承诺是 Durability(持久性),ACID 的 D(Atomicity 原子性、Consistency 一致性、Isolation 隔离性、Durability 持久性;形容词 atomic、consistent、isolated、durable)。WAL(Write-Ahead Log,预写日志)就是不用每次提交都刷数据页、也能兑现这个承诺的办法。

铁律一条。 数据页可以晚落盘,但描述改动的日志记录,必须先落盘,这个事务才许提交。"先"(ahead)永远是相对于数据页落盘而言,不是相对于内存改动。

第一幕——顺利路径。 走一次提交(主角仍是 accounts id=7,balance 100 改 80,事务 742)。(1) 每次改动,先往 WAL 缓冲区追加一条日志记录——"事务 742 把某页改成了这样",每条带递增序号 LSN;然后才改内存里的数据页(mvcc 的版本照常生成)。(2) 敲下 COMMIT:把 WAL 缓冲刷盘 + fsync,fsync 落地之后才返回"提交成功"。注意此刻改过的数据页可能还只活在内存里——但这次提交已经完全算数,因为日志能把页重建出来。(3) 之后 checkpoint 在后台把脏页慢慢刷盘,并把"日志可以回收到哪一段"的界线往前推。顺利路径上不会发生的事:提交时刷数据页、提交时等 checkpoint。提交延迟约等于一次顺序追加 + 一次 fsync。(回滚也是常态流量:事务撤销自己的改动,撤销动作本身也记成日志——补偿记录——这样 undo 做到一半崩溃也不会把故事讲乱。)

第二幕——崩溃。 断电那一刻,内存全灭:没刷盘的数据页、WAL 缓冲里没 fsync 的尾巴,一起没。盘上幸存:已 fsync 的 WAL(到某个 LSN 为止)+ 以前 checkpoint 刷好的数据页(可能相当旧)。重启恢复三步,顺序不能乱。(1) 定位:从控制文件读出最后一个 checkpoint 的位置——只有它之后的日志可能还没进数据页。(2) Redo(先重做):按 LSN 顺序逐条重放,不管事务提交没提交,先把物理世界恢复成崩溃前最后一刻的样子。重放为什么放不坏:每个数据页页头存着 page LSN——"我已经吸收到的最新日志号";一条记录只有在目标页的 page LSN 落后于它时才真重放,否则跳过。于是重放幂等,恢复中途二次断电、重启再来一遍,结果不变。(3) Undo(再回滚):清点崩溃时未提交的事务,用日志把它们的改动逐条抹掉,抹的动作同样记成补偿记录。结束状态:已提交的一个不少,未提交的一个不剩——像崩溃只是一次暂停。

三份"副本"的图景。 同一个逻辑状态的三种时态:内存里的页是现在时,磁盘上的数据页是过去时,WAL 是把过去时推回现在时的那串动词。写成等式:数据页 +(checkpoint 之后那段)日志 ≡ 内存里的状态。三者在内容上并不相同,是靠那条铁律保持"代表同一状态"的等价。

为什么写日志便宜——它明明也在磁盘上。 三条。(1) 顺序 vs 随机:日志是往一个文件尾巴追加,笔不抬头;数据页散在整个文件各处,刷页是随机 IO——机械盘贵在寻道,SSD 贵在写放大。(2) 写得少:一条日志只记改动本身,几十到几百字节;刷一页是整页 8KB/16KB,改一个字节也全额陪绑。一个事务动了十个分散的页:刷页 = 10 次随机整页写,写日志 = 一小段连续追加。(3) 只写一处、还能拼单:一次提交只 fsync 一条流,排队的多个事务还能共享同一次 fsync(group commit)。WAL 不是不落盘,是把躲不掉的落盘整形成磁盘最喜欢的样子:顺序的、增量的、一次的。(合并整理的活由 checkpoint 在后台干:一页被改十次,只刷最终版一次。)

同族不同物——WAL 与 MVCC 版本。 两者都是只追加的改动记录,像不是错觉(InnoDB 的 undo log 还一物两用兼任旧版本仓库)。区别在:岗位不同(版本管活着时读写分离,WAL 管死后复活);形态不同(版本散在各行身上、没有全局顺序,WAL 是一条全局有序的流);最硬的一条是落盘纪律不同——版本可以只活在内存里、崩溃即蒸发,WAL 必须被逼着先落盘才算数。持久性来自这个"逼",不来自"叠"。

read next
about this entry

One of sijie's wiki entries. The AI on this site is grounded in the same corpus and answers in sijie's voice, with citations back to entries like this one — answering costs sijie money, so it waits behind a code: enter an access code →