innodb崩溃后秒级可用,因其重启时自动执行crash recovery:依赖ib_logfile0重做日志前滚已提交事务,并利用ibdata1中双写缓冲区校验并修复撕裂页;myisam无日志与页保护,仅靠易失效的.myi标记位判断崩溃,必须人工repair且常失败。

InnoDB崩溃后秒级自动恢复,MyISAM大概率卡住报 Table 'db.t1' is marked as crashed and should be repaired ——这不是“慢一点”,而是服务能否继续的问题。
崩溃后MySQL重启时,InnoDB怎么做到秒级可用?
InnoDB启动时自动执行crash recovery流程,整个过程对应用完全透明,无需人工干预或修改代码。它依赖两个核心组件:ib_logfile0(重做日志)和ibdata1中的双写缓冲区(doublewrite buffer)。
-
ib_logfile0记录所有已提交但尚未刷入数据文件的变更,重启时前滚(redo)这些操作 - 双写缓冲区默认开启,先将变更页顺序写入
ibdata1里连续2MB区域,落盘成功后再并发写入真实.ibd文件;崩溃后校验该区域页是否完整,是则直接覆盖回.ibd - 若
innodb_force_recovery被设为1~6,仅在极端日志损坏时启用,日常无需配置
MyISAM为什么一断电就报错、必须人工修复?
MyISAM没有事务日志,也没有页级保护机制,崩溃判断仅靠.MYI文件头一个易失效的标记位。一旦标记异常,就拒绝服务,不尝试恢复,只报错。
- 修复不是“还原”,而是用
.MYI反推.MYD偏移,索引若也损坏(很常见),就彻底没辙 -
REPAIR TABLE会锁整张表,TB级表修复可能持续几十分钟,期间读写全阻塞 -
CHECK TABLE返回OK不代表安全——.MYI静默损坏可能导致查询结果错乱或丢行 - 即使启用
myisam_recover_options,MySQL 5.7+ 默认已禁用自动修复,需显式开启
撕裂页(torn page)问题暴露根本差异
磁盘写入一个16KB页时,若断电发生在第8KB处,就会产生撕裂页。InnoDB能救回来,MyISAM直接丢数据。
- InnoDB靠双写缓冲实现页级防护:先写双写区,再写真实文件;崩溃后用双写区完整页覆盖修复
- MyISAM无此备份层,
.MYD里就存着半截脏页,REPAIR TABLE无法识别或补全 - 禁用
innodb_doublewrite=OFF等于主动放弃这层防护,生产环境不应碰 -
delay_key_write=ON会让MyISAM连索引都不落盘,断电后索引丢失更频繁
主从复制场景下,崩溃影响完全不同
从库宕机重启后,InnoDB表能自动续传relay log;MyISAM表崩溃会导致复制线程直接卡死,SHOW SLAVE STATUS显示Slave_SQL_Running: No,且无法跳过。
- 这是因为MyISAM的崩溃状态污染整个表结构,SQL线程一碰到就报错退出
- InnoDB的事务日志让relay log可精确重放,未提交事务自动回滚,已提交事务前滚完成
- 哪怕只是日志表、统计表这类“不重要”数据,用MyISAM就得接受某次断电后昨天的PV归零
真正容易被忽略的是:MyISAM的“轻量”只在系统永远不崩溃的前提下成立。它的可靠性成本全堆在运维响应上——而线上系统从不承诺永不崩溃。











