myisam 不建议用于生产环境,根本原因是缺乏日志机制(无undo log和redo log),无法保障数据完整性,崩溃后无法检测或恢复脏数据,易导致索引与数据错位、主从不一致等严重问题。

MyISAM 在生产环境不建议使用,根本原因不是性能差,而是它完全无法保障数据完整性——哪怕一条 INSERT 中途失败,或一次断电,都可能留下错位、半截、不可验证的脏数据。
MyISAM 崩溃后“自己都不知道数据坏了”
MyISAM 把数据直接写进 .MYD 文件、索引写进 .MYI 文件,没有任何日志机制。没有 UNDO LOG,没法回滚;没有 REDO LOG,崩溃后没法前滚恢复;连校验和都没有,更不会主动检测文件是否一致。
常见表现:
-
Table is marked as crashed and should be repaired频繁报错,但REPAIR TABLE只是暴力重写索引,不能保证逻辑正确 -
SELECT COUNT(*)和SELECT * FROM t WHERE id > 1000返回矛盾结果(索引计数 vs 实际行数不一致) - 主从复制中某条
REPLACE INTO在从库执行后数据“看起来正常”,但业务核对发现金额/状态错乱,且无任何错误日志
InnoDB 的 ACID 是默认硬启用的,MyISAM 连“事务”这个词都不认
很多人误以为“我不写 BEGIN 就没事务”,但在 InnoDB 中:autocommit=1 是默认行为,每条 INSERT/UPDATE/DELETE 都是独立事务,原子性由 UNDO LOG 保障;innodb_flush_log_at_trx_commit=1 确保每次 COMMIT 都刷盘,崩溃后可完整恢复。
而 MyISAM:
-
FOREIGN KEY语法会被直接忽略(只当注释),外键约束形同虚设 -
INSERT ... ON DUPLICATE KEY UPDATE实际执行为“先删后插”,自增 ID 跳变,且删除与插入无法原子化 -
SELECT ... FOR UPDATE不生效,MyISAM 只支持表级锁,FOR UPDATE被静默忽略,应用层以为加了锁,其实并发写入仍在发生
MyISAM “读得快”是假象,代价是数据不可信
在只读、低频、全量导出的归档表场景下,MyISAM 确实体积小、扫描快。但只要涉及以下任一操作,风险就立刻暴露:
- 有写入:哪怕只是定时
INSERT ... SELECT汇总,中断即导致部分写入、索引错位 - 有并发:两个
UPDATE同时改同一张表,MyISAM 表级锁会让中间态暴露时间更长,更容易被读到不一致数据 - 有备份:
mysqldump --single-transaction对 MyISAM 表会退化为全局FLUSH TABLES WITH READ LOCK,整个库写入阻塞
真正容易被忽略的是:MyISAM 的“可用”往往出现在测试或初期阶段,等数据量上来、业务逻辑变复杂、故障真实发生时,修复成本远高于初期换引擎的成本。











