mysql 5.7后不推荐生产环境用myisam,根本原因是缺乏undo/redo日志导致数据完整性完全不可控:断电或中断操作易致索引与数据错位、主从不一致、表级锁阻塞高并发,且崩溃后无法自检恢复。

MySQL 5.7 之后不推荐在生产环境用 MyISAM,根本不是因为它“慢”或者“老”,而是它在数据完整性上完全不可控——一次断电、一条中断的 INSERT、甚至一个未完成的 ALTER TABLE,都可能让表处于“看起来正常,实则逻辑错乱”的状态,且数据库自己毫无察觉。
MyISAM 崩溃后无法自检或恢复
MyISAM 没有 UNDO LOG,也没有 REDO LOG,所有变更直接写入 .MYD(数据)和 .MYI(索引)文件。崩溃发生时:
- 索引与数据文件可能不同步,
SELECT COUNT(*)和SELECT * FROM t WHERE id > 1000返回矛盾结果 -
REPAIR TABLE只是暴力重建索引,不验证业务逻辑是否一致 - 主从复制中,从库执行完
REPLACE INTO后看似成功,但金额/状态已错位,且无任何错误日志可查
表级锁在高并发下直接卡死业务
只要有一条 UPDATE 在跑,整张 MyISAM 表就锁死,其他读写全部排队:
-
SHOW PROCESSLIST中大量出现Waiting for table level lock - 用户中心、订单、库存类表一压就堵,而
InnoDB默认行级锁,张三改第 5 行、李四改第 200 行互不影响 - 注意:如果
InnoDB的WHERE条件没走索引(比如status=1但status无索引),也会升级为表锁——这点容易误以为“InnoDB 也不行”,其实是用法问题
禁用 MyISAM 不等于删除,但绕过限制太容易
MySQL 5.7.28+ 支持 disabled_storage_engines="MyISAM",但仅限初始化加载阶段:
- 重启后
CREATE TABLE ... ENGINE=MyISAM会报ERROR 1286 (42000): Unknown storage engine 'MyISAM' - 但
CREATE TABLE t AS SELECT * FROM myisam_table仍会生成MyISAM表——因为沿用源表引擎,不校验白名单 - 从
mysqldump导入的 SQL 若含ENGINE=MyISAM,服务端照样执行(尤其旧版本备份还原到新环境时) - 已有
MyISAM表不受影响,仍可读写,直到你主动转换或引擎被彻底卸载
InnoDB 已成事实标准,MyISAM 连系统表都弃用了
MySQL 8.0 起,所有系统表(mysql.*、performance_schema、information_schema)全部强制使用 InnoDB:
-
ALTER TABLE t ENGINE=InnoDB看似一行命令,实际是全量拷贝 + 重建索引 + 重写聚簇结构,千万级表需低峰期操作 - 磁盘空间要预留约 1.5 倍原表大小;
FLOAT/DOUBLE字段在某些版本中InnoDB会拒绝NULL,需先ALTER COLUMN ... SET DEFAULT 0 -
mysqldump --single-transaction对MyISAM无效,但对InnoDB可实现秒级一致性热备
真正危险的不是“现在还能用”,而是“现在没出事,所以觉得能继续用”。一旦涉及并发更新、主从一致性、异常恢复或在线 DDL,MyISAM 的脆弱性就会在某个凌晨三点精准爆发——而且没有日志告诉你哪里坏了。











