myisam 不适用于 oltp 场景,因其缺乏事务、崩溃恢复能力及并发写入支持;表级锁导致高延迟与请求堆积;禁用配置无法彻底阻止使用,须主动清退并迁移至 innodb。

因为 MyISAM 在 OLTP 场景下无法保障数据一致性、并发可用性与故障恢复能力——这不是性能优劣问题,而是根本性能力缺失。
MyISAM 的表级锁会直接卡死核心业务链路
OLTP 业务(如订单创建、库存扣减、账户余额更新)天然具备高频率、小事务、多并发写入特征。MyISAM 对任何 INSERT、UPDATE、DELETE 都施加整表排他锁,且写锁优先级高于读锁。
- 一个慢
UPDATE执行 2 秒,期间所有对该表的SELECT(包括登录鉴权、商品详情查询)全部排队等待 - 多个并发写请求会形成锁队列,响应时间呈指数增长;监控上表现为
Table_locks_waited持续飙升、Lock_time_avg超过 1s - MySQL 不会主动中断或降级,应用层只能超时失败,导致“看似没报错,但大量请求 504”
没有事务和崩溃恢复机制,一次异常就可能丢数据
OLTP 业务要求 ACID,而 MyISAM 完全不支持:
-
INSERT ... SELECT或批量INSERT过程中若发生断电、OOM 或kill -9 mysqld,已写入部分无法回滚,未写入部分不会补全 → 表处于“半截状态”,CHECK TABLE报error: 126 / 134 / 144 - 转账类逻辑(如 A 减、B 加)必须成对成功,MyISAM 下前一条成功、后一条失败 → 资金凭空蒸发,
BEGIN/COMMIT根本无效 - 崩溃重启后,MyISAM 依赖
myisamchk或REPAIR TABLE,但 SSD I/O 错误或文件偏移不一致时,修复可能损坏更多数据
disabled_storage_engines 配置不能完全封死 MyISAM
即使你已在 my.cnf 中设置 disabled_storage_engines="MyISAM",仍存在绕过路径:
-
CREATE TABLE ... SELECT从已有 MyISAM 表复制时,新表默认继承引擎,不校验配置 - 通过
mysql命令导入含ENGINE=MyISAM的备份 SQL 文件,只要服务端版本低于 5.7.28,就会直接执行 -
ALTER TABLE ... ENGINE=MyISAM在引擎已加载状态下可能成功(MySQL 8.0.23+ 已修复,但旧版本仍存在) - 该配置不影响已存在的 MyISAM 表读写,也不阻止 MySQL 内部临时表使用 MyISAM(尤其在排序/聚合时)
真正要做的不是“禁用”,而是“清退”
禁用配置只是防线之一,生产环境必须主动清理存量:
- 用
SELECT TABLE_SCHEMA, TABLE_NAME FROM information_schema.TABLES WHERE ENGINE = 'MyISAM';扫描全库 - 对非系统表逐个执行
ALTER TABLE xxx ENGINE=InnoDB;(注意:大表需评估锁表时间,建议在低峰期 +pt-online-schema-change) - 检查
mysql系统库是否还有 MyISAM 表(MySQL 8.0 应全为 InnoDB;若发现,说明升级未完成或手动改过) - CI/CD 流水线中加入建表语句检查,拒绝含
ENGINE=MyISAM的 DDL 提交
最易被忽略的一点:MyISAM 表即使只读,也会占用独立的 key_buffer_size 缓存,与 InnoDB 的 buffer_pool 互不共享——资源隔离反而造成内存浪费,且无法通过统一调参优化整体性能。











