disabled_storage_engines配置仅在MySQL 5.7.28+和8.0.19+有效,须置于my.cnf的[mysqld]段、用英文双引号包裹、重启生效;低版本启动报unknown variable;CREATE TABLE SELECT等操作可能绕过限制,mysql_upgrade时亦会因禁用MyISAM报错3161。

disabled_storage_engines 配置必须写对位置和格式
这个参数只在 MySQL 5.7.28+ 和 8.0.19+ 有效,低于这些版本会启动失败,报错 unknown variable 'disabled_storage_engines'。确认版本用 SELECT VERSION();。
它只能写在 my.cnf 的 [mysqld] 段里,不能用 SET GLOBAL 动态设置,改完必须重启服务。
值必须是英文双引号包裹的字符串,多个引擎用英文逗号分隔,例如:disabled_storage_engines = "MyISAM,ARCHIVE"。漏掉引号、用单引号、多一个空格,都会静默失效。
常见误操作包括:把配置写进 /www/server/mysql/my.cnf 却没被读取(MySQL 8.0 默认只认 /etc/my.cnf 等固定路径);在 --skip-grant-tables 或 --initialize 模式下启动时,该配置自动失效。
CREATE TABLE SELECT 是最常被忽略的绕过点
执行 CREATE TABLE t2 AS SELECT * FROM t1 时,如果 t1 是 MyISAM 表,新表 t2 会默认继承 MyISAM 引擎,且完全不校验 disabled_storage_engines——因为 MySQL 认为这是“复用已有引擎”,不是“新建请求”。
验证是否绕过:执行后立刻查 SELECT ENGINE FROM information_schema.TABLES WHERE TABLE_NAME = 't2';
安全写法是强制指定引擎:CREATE TABLE t2 ENGINE=InnoDB AS SELECT * FROM t1;
同理,从 SQL 备份文件恢复时,若语句含 ENGINE=MyISAM,也会跳过检查直接建表,除非服务端版本根本不支持该引擎(此时才报错)。
mysql_upgrade 升级时会因禁用报错,需临时放开
执行 mysql_upgrade 可能触发 [ERROR] 3161: Storage engine MyISAM is disabled,因为旧版升级脚本可能尝试重建某些历史兼容表。
这不是数据损坏,而是升级流程卡在非必要步骤。解决方法明确:
- 临时注释掉配置文件中的
disabled_storage_engines = MyISAM - 重启 MySQL,再运行
mysql_upgrade - 升级完成后,重新启用该配置并重启
该过程无需停业务太久,且只影响升级窗口期——日常运行中该参数完全静默生效。
SHOW ENGINES 显示 MyISAM 为 YES 是假象
SHOW ENGINES 里 MyISAM 仍显示为 YES,这只是状态展示残留,实际不可用。真正判断是否禁用成功,应以建表报错为准。
以下语句执行时会立即失败,错误码统一为 3161:
CREATE TABLE t1 () ENGINE=MyISAMALTER TABLE t2 ENGINE=MyISAMCREATE TEMPORARY TABLE tmp () ENGINE=MyISAM- 任何试图将现有表转为 MyISAM 的 DDL
真正难排查的是那些没报错、只是结果异常的场景:比如某个存储过程里用 CREATE TEMPORARY TABLE 未指定 ENGINE,而旧环境默认是 MyISAM,新环境默认变成 InnoDB 后,因事务行为差异导致中间状态不一致——这种必须结合业务逻辑回归验证。


















