MySQL 为什么需要 Doublewrite?有了 redo log 还不够吗?
🧑💻 面试官:有 redo log,为什么 InnoDB 还需要 Doublewrite?
🙋♂️ 我:再写一份,是为了多做一次备份。
🧑💻 面试官:备份可以找回误删的数据,这份中间页也能吗?
🙋♂️ 我:不能,它应该是防止页写坏。
🧑💻 面试官:如果原来的页只写了一半,redo 为什么不能直接在坏页上恢复?
redo 负责重做修改,Doublewrite 负责在页写坏时提供完整页。一个恢复“做过什么”,一个先保证“有能恢复的页”。
面试速答(60 秒版)
Doublewrite 主要防的是数据页写入中途发生故障,导致页只更新了一部分。数据库页的大小和底层写入单位并不天然一致,页写入不一定是原子的。
刷页时,InnoDB 会先把页写到 Doublewrite 区域,再写到数据文件的目标位置。恢复时如果目标页损坏,可以用完整副本修复,再结合 redo 完成必要重做。
redo 记录修改,不是给每次修改都保存一份完整数据页,所以它和 Doublewrite 不是重复功能。
Doublewrite 也不是业务备份,不能靠它找回误删。是否关闭,要验证底层原子写保障和故障风险,不能因为用了 SSD 就直接关闭。

知识点详解:先把页修完整,再谈重做修改
先看“只写了一半”是什么意思
假设一个数据页原本完整,数据库准备把更新后的整页写回。写入过程中突然断电,目标位置可能留下部分新内容和部分旧内容。
这是页损坏,不只是“少执行了最后一条 SQL”。页头、校验、记录结构等可能不再相互对应。这里用一半帮助理解,实际受存储和文件系统写入行为影响,不一定恰好一半。
数据库管理一个页,不代表设备保证这一页在故障时全部成功或全部失败。SSD 也不能直接等同于数据库页级原子写。
redo 需要可用的恢复基础
redo 可以记录页上的修改,并在崩溃恢复中把必要修改重新做一遍。但它不是每次都附带完整的、可独立替换原页的镜像。
当页本身已经破坏,不能简单把增量修改往任意坏内容上叠加,就指望重新得到正确页。先获得完整页,再做重做,才把两个不同问题接起来。
因此“有日志就不怕任何数据文件损坏”是范围过大的说法。恢复机制都有适用故障模型。
Doublewrite 保存一次安全落脚点
刷页时,页先写入 Doublewrite 文件中的位置,并按相应持久化规则完成这一阶段,随后才写到数据文件的最终位置。
如果最终位置写坏,恢复过程有机会从中间区域找到良好的页副本。它是刷页过程里的保护,不是一份按业务时间长期保留的历史备份。
“两次写”也不意味着所有 IO 开销精确翻倍。中间区域可以批量顺序写,成本要看页批次、设备和配置,不能用次数直接推算吞吐下降一半。
不要把所有配置模式都当成能修复
MySQL 8.4 文档区分正常检测与恢复、只检测,以及关闭等模式。只检测模式不保存用于修复的完整页内容,不能当作完整保护。
若要减少成本,先在隔离环境测写入和刷页压力,再确认原子写是否确实覆盖所有相关数据文件。某个盘支持某种能力,不代表整个实例每条写入路径都满足。
误删、逻辑错误、文件丢失仍需要独立备份和恢复演练。Doublewrite 解决的是页写入完整性,不是数据库所有故障。
本题机制参考:Doublewrite Buffer、Redo log、崩溃恢复。
面试官继续追问
Doublewrite 能代替 redo 吗?
不能。完整页副本和事务修改重做职责不同,副本不保证包含全部需要恢复的事务修改。
用了 SSD 就可以关闭吗?
不能直接这样判断。要核实设备、文件系统和数据库实际启用的页级原子写能力,普通 SSD 标签不提供这个结论。
两次写是不是性能减半?
不一定。批量和顺序写会影响实际成本,应该测刷页吞吐与请求延迟,不能用两次推算两倍。
面试速记卡
- 故障:写入中途可能留下部分新、部分旧的页。
- Doublewrite:先保留完整页,再写目标位置。
- redo:重做必要修改,不等于完整页备份。
- 边界:只检测模式不提供同等修复能力。
- 选型:SSD 不等于页级原子写,备份仍然需要。
公司面试真题
这道题暂未收录可核验的公司真题来源。你可以先阅读本文解析,或浏览已收录的公司面试真题。
浏览公司面试真题 →