myisam不支持双写缓冲区,因其无页概念、无事务机制、无崩溃后页级恢复能力;innodb依赖双写缓冲区保障页写入原子性与崩溃恢复,是crash recovery的必要环节而非可选优化。

因为MyISAM压根不设计事务日志和页级原子写入机制,双写缓冲区(doublewrite buffer)对它没有意义——它既不保证页完整落盘,也不在崩溃后做页级校验与恢复。
Doublewrite buffer 是 InnoDB 崩溃恢复的底层依赖
InnoDB 的 ib_logfile0(重做日志)只记录逻辑变更,不能直接修复物理损坏的页;而磁盘写入可能因断电卡在中间(撕裂页),所以需要一个“安全中转站”:先将变更后的 16KB 数据页顺序写入 ibdata1 中连续的 2MB 双写区,确认落盘后再并发写入真实 .ibd 文件。崩溃重启时,InnoDB 检查双写区里的页是否完整,是则直接覆盖回数据文件。
这个流程决定了 doublewrite 是 crash recovery 的必要环节,不是可选优化。
- 开启状态由
innodb_doublewrite控制,默认为ON - 关闭后(
OFF或COMPATIBLE),InnoDB 仍能运行,但撕裂页风险上升,mysqld启动时不再尝试从双写区恢复 - MyISAM 完全跳过这一步:它把
.MYD当作裸字节流直写,不校验页完整性,也不保存任何副本
MyISAM 没有页概念,也没有崩溃后自动页修复能力
MyISAM 表数据存于 .MYD 文件,索引存于 .MYI,两者独立且无关联校验机制。它的“修复”本质是离线重建:myisamchk --recover 或 REPAIR TABLE 会扫描 .MYI 索引项,再按偏移去 .MYD 里捞数据——一旦索引损坏或偏移错位,就丢行、乱序、主键重复。
它不区分“页”,不缓存页,不刷页,也不需要保证单次写入的原子性。所以:
- 没有
doublewrite对应的概念,也不存在配置项 - 断电后若
.MYD写到一半,MySQL 启动时只会报Table 'db.t1' is marked as crashed and should be repaired,然后卡住不动 - 即使你手动执行
REPAIR TABLE,它也不会读任何“备份页”,只是硬拼
为什么不能给 MyISAM 加个 doublewrite?
技术上可以强行加,但违背设计哲学:MyISAM 的定位就是轻量、快读、无事务。加上 doublewrite 就意味着引入页管理、缓冲池、写顺序控制、崩溃时页比对逻辑——这等于重写一套 InnoDB 的基础模块。
真正关键的取舍点在于:
- InnoDB 把“页”作为核心单位,所有持久化、锁、MVCC、恢复都围绕它展开;doublewrite 是其页模型的自然延伸
- MyISAM 把“记录”作为单位,
.MYD是堆式追加,.MYI是 B+ 树索引指针,二者松耦合,没有统一的页生命周期管理 - 加了 doublewrite 也救不了 MyISAM 的根本缺陷:没有 undo log、没有事务上下文、没有行级一致性视图
真正容易被忽略的是:双写缓冲区不是性能功能,而是容错底线。哪怕你关掉 innodb_doublewrite 来压测 IO,只要遇到真实断电,InnoDB 就可能像 MyISAM 一样丢页——只是概率低得多。而 MyISAM 从没打算跨过这条线。











