必须先清空业务表和系统表中的myisam引擎表,否则mysqld启动会报错[my-010929];禁用后create/alter显式指定engine=myisam将直接报error 3161,且隐性行为变化(如临时表默认引擎、全文索引、并发插入)可能导致业务逻辑偏移,需端到端回归验证。

能禁,但必须先确认业务表和系统表是否已清空 MyISAM 依赖,否则服务可能无法启动或查询直接失败。
查清楚当前还有哪些 MyISAM 表在跑
别信 SHOW ENGINES 里 MyISAM 显示为 YES——那是状态残留,实际是否可用得看建表是否报错。真正要盯的是数据表本身:
- 查业务库:
SELECT table_name, engine FROM information_schema.tables WHERE table_schema = 'your_db' AND engine = 'MyISAM'; - 查系统库(更关键):
SELECT table_name, engine FROM information_schema.tables WHERE table_schema = 'mysql' AND engine = 'MyISAM';——只要有一张,mysqld 启动就会拒绝加载,报错类似[MY-010929] Storage engine 'MyISAM' does not support system tables - 注意:
mysqldump导出的 SQL 文件里若含ENGINE=MyISAM,恢复时不会被disabled_storage_engines拦截,会静默建出 MyISAM 表
禁用后哪些语句会立刻报 ERROR 3161
MySQL 5.7.8+ 启用 disabled_storage_engines = "MyISAM" 后,以下操作不再等待、不走兼容逻辑,直接返回错误:
CREATE TABLE t1 (...) ENGINE=MyISAMALTER TABLE t2 ENGINE=MyISAMCREATE TEMPORARY TABLE tmp (...) ENGINE=MyISAM- 任何显式指定
ENGINE=MyISAM的 DDL
但要注意漏网之鱼:CREATE TABLE t2 AS SELECT * FROM t1 如果 t1 是 MyISAM 表,新表默认继承引擎,且不校验 disabled_storage_engines;必须写成 CREATE TABLE t2 ENGINE=InnoDB AS SELECT * FROM t1 才安全。
升级和运维流程是否被阻断
公有云环境常自动触发 mysql_upgrade 或内核级检查,而该工具在 MySQL 8.0.16+ 已废弃,但部分云厂商控制面仍调用它——一旦配置了 disabled_storage_engines = "MyISAM",就会卡在 [ERROR] 3161: Storage engine MyISAM is disabled。
- 临时解法:升级窗口期前,注释掉配置,重启实例,跑完升级再恢复配置
- 更稳妥做法:改用
mysqld --upgrade=FORCE(需绝对路径 + root 权限),绕过mysql_upgrade脚本 - 监控脚本、备份工具(如老版本
mysqldump --skip-create-options)若硬编码ENGINE='MyISAM'条件,查询information_schema.TABLES会漏匹配,导致巡检失效
隐性行为变化比报错更危险
最麻烦的不是语法报错,而是逻辑偏移:
- 存储过程里
CREATE TEMPORARY TABLE tmp (...)没写ENGINE,旧环境默认 MyISAM(无事务),新环境默认 InnoDB(有事务),中间状态可能因未提交而不可见,导致业务判断失准 - MyISAM 默认
concurrent_insert=2带来的“伪并发插入”被取消,所有 INSERT 都走 InnoDB 行锁+事务日志路径,吞吐模型变了,需重看慢查询和锁等待指标 - 全文索引行为差异:MyISAM 的
FULLTEXT分词简单粗暴,InnoDB 的分词器、停用词列表、布尔模式支持都不同,搜索结果可能大面积漂移,不能只看建表成功
真正难验证的,是那些没报错、日志也干净、但业务侧资金/状态/计数对不上的场景——必须结合核心链路做端到端回归,而不是只跑通 DDL。











