myisam没有redo log,因其设计上不支持事务和崩溃恢复,所有写操作直接刷盘,无内存中间态与wal机制;崩溃后只能依赖repair table暴力重建索引,无法重放日志恢复。

MyISAM 没有 redo log,是因为它压根不支持事务和崩溃恢复——不是“忘了加”,而是设计上就不要。
MyISAM 的写入模型根本不依赖 WAL 机制
redo log 是 WAL(Write-Ahead Logging)机制的产物,而 WAL 的前提是有“未落盘但已提交”的状态需要保护。MyISAM 没有 buffer pool,所有 INSERT、UPDATE、DELETE 都是直接刷盘(fsync 到 .MYD 文件),也不区分“内存修改”和“磁盘持久化”。没有中间态,自然不需要记“重做流水账”。
- 每条语句执行完就调用
write()+fsync(),数据页和索引页(.MYI)同步更新 - 没有事务概念,
START TRANSACTION和ROLLBACK对 MyISAM 表完全无效 - 崩溃时若写到一半(比如只写了 .MYD 没写完 .MYI),文件就处于错位状态,无法靠日志“重放”修复
MyISAM 的崩溃恢复只能靠人工 repair
当 MySQL 异常退出,MyISAM 表可能处于“数据文件与索引文件偏移不一致”的状态。这时 REPAIR TABLE 或 myisamchk 并不是重放日志,而是暴力重建索引、扫描数据文件重新生成 .MYI —— 它不验证业务逻辑是否正确,只保证结构可读。
-
CHECK TABLE报error: 126(索引损坏)或error: 144(记录链断裂)是典型信号 - SSD 坏块、内核 I/O 错误、OOM kill 进程都可能导致 repair 后数据丢失
- 主从复制中,从库执行
REPLACE INTO后看似成功,但金额/状态已错位,且SHOW SLAVE STATUS不报错
InnoDB 的 redo log 是 crash-safe 的基础设施
redo log 不是可选插件,而是 InnoDB 实现 ACID 中 “D(Durability)” 的硬性依赖。它记录的是物理页变更(如“页号 12345,偏移 678,写入 4 字节新值”),而非 SQL 逻辑。
- 必须在
COMMIT前刷盘(由innodb_flush_log_at_trx_commit=1控制),否则事务不算真正持久 - 日志文件循环使用(默认总容量由
innodb_redo_log_capacity控制),靠 LSN(Log Sequence Number)推进 checkpoint - 崩溃重启时,InnoDB 自动重放 redo log 中已提交但未刷入 data file 的修改,整个过程无需 DBA 干预
真正容易被忽略的点在于:即使你建表时没显式写 ENGINE=InnoDB,也不能默认它就是 InnoDB——旧配置、迁移脚本、mysqldump 导出的 SQL 都可能带 ENGINE=MyISAM,而 MySQL 5.7+ 默认仍允许创建,只是官方早已弃用。确认引擎的唯一可靠方式是查 SHOW CREATE TABLE t,而不是看文档或想当然。











