mysql 8.0 已彻底移除 myisam 引擎支持,非禁用而是内核级删除;必须通过 select 定位所有 myisam 表(含 mysql 库),并用 mysqld --upgrade=force 强制转换系统表,业务表推荐 pt-online-schema-change 平滑迁移。

MySQL 8.0 已彻底移除 MyISAM 引擎支持,不是“禁用”或“不推荐”,而是内核级删除——SHOW ENGINES 中 MyISAM 的 Support 列固定为 NO,任何残留都会导致启动失败、导入中断或查询报错 Unknown storage engine 'MyISAM'。必须清零,没有例外。
如何快速定位所有 MyISAM 表(含系统库)
别依赖经验或配置文件,直接查数据字典。MyISAM 残留常藏在 mysql 库里(比如 mysql.columns_priv),这类表哪怕只有一张,mysqld 启动就会拒绝加载:
- 查业务库:
SELECT table_schema, table_name, engine FROM information_schema.tables WHERE table_schema NOT IN ('mysql', 'information_schema', 'performance_schema') AND engine = 'MyISAM'; - 查系统库(关键!):
SELECT table_name, engine FROM information_schema.tables WHERE table_schema = 'mysql' AND engine = 'MyISAM'; - 如果第二条有结果,
mysqld --upgrade=FORCE是唯一解,不能跳过
系统表 MyISAM 残留导致启动失败怎么办
错误日志出现 [MY-010929] Storage engine 'MyISAM' does not support system tables,说明 mysql 库里有 MyISAM 表。这不是配置问题,也不是权限问题,是升级流程卡住:
-
mysql_upgrade在 8.0.16+ 已废弃,执行它只会输出mysql_upgrade is deprecated,完全无效 - 必须用新版本
mysqld二进制显式触发内核级迁移:mysqld --user=mysql --datadir=/var/lib/mysql --upgrade=FORCE - 路径必须绝对准确,
systemctl start mysql不会传递--upgrade参数,不能替代 - 执行前确认:
ps aux | grep mysqld无残留进程;my.cnf中临时注释掉innodb_force_recovery;磁盘剩余空间 ≥ 2GB
业务库 MyISAM 表怎么转成 InnoDB 才不卡死服务
ALTER TABLE t ENGINE=InnoDB 在 MySQL 8.0 中仍强制走 COPY 算法,全程持有 MDL 写锁,大表会阻塞读写、拖垮主从。真要平滑迁移,只有一条路:
- 先确认前提:
innodb_file_per_table = ON(5.6+ 默认开启)、表有显式主键或唯一非空索引、binlog_format = ROW - 用
pt-online-schema-change:它建影子表 + 触发器双写,业务几乎无感。示例命令:pt-online-schema-change --alter "ENGINE=InnoDB" D=your_db,t=big_table --execute --chunk-size=1000 --max-lag=1 - 注意:
pt-osc迁移后不会自动删旧的.MYD和.MYI文件,必须人工验证CHECKSUM TABLE一致后再清理 - 转换后务必调参:
innodb_buffer_pool_size设为物理内存 50%–75%,key_buffer_size降到 32M 左右
导出/导入时 MyISAM 表容易被忽略的坑
mysqldump 不会自动改引擎,dump 文件里仍带 ENGINE=MyISAM,在 8.0 下要么报错,要么静默降级为 InnoDB 但不提示。这会导致导入后行为不一致:
- 导出前必须清零:
SELECT CONCAT('ALTER TABLE `', table_name, '` ENGINE = InnoDB;') FROM information_schema.tables WHERE table_schema = 'your_db' AND engine = 'MyISAM';批量生成语句执行 - 导出时加
--single-transaction没用——它只对 InnoDB 表生效,只要库中还有一张 MyISAM 表(哪怕是mysql.general_log),快照就不一致 - 导入后立刻验证:
SELECT table_name, engine FROM information_schema.tables WHERE table_schema = 'your_db';,别信 dump 文件里的注释
最易被忽略的是系统库残留和 --upgrade=FORCE 的执行方式——它必须由 mysqld 主进程直接运行,不是服务管理命令能触发的。一旦漏掉,后续所有操作都在错误前提下进行。











