MySQL 8.0 并未完全废弃 MyISAM 引擎,而是移除系统表对它的依赖以支持原子 DDL;用户仍可创建 MyISAM 用户表,但 mysql 库下所有表强制使用 InnoDB,因 MyISAM 不支持事务与崩溃安全回滚。

MySQL 8.0 并非“完全废弃 MyISAM”,而是彻底移除了系统表(mysql 库下所有表)对 MyISAM 的依赖——这是原子 DDL 能落地的硬性前提。
为什么系统表不能继续用 MyISAM
MyISAM 是非事务引擎,不支持崩溃安全的回滚。而 MySQL 8.0 要实现原子 DDL,就必须让「元数据变更」本身可回滚。如果 mysql.user 还是 MyISAM 表,那执行 DROP USER 时:
- 先删
mysql.user行 → 成功写入磁盘 - 再删认证插件状态或权限缓存 → 中途 crash
- 重启后用户记录已丢,但权限残留或缓存未清,状态不一致
这种分裂更新在 5.7 及以前真实存在,也是运维半夜被叫醒的常见原因。
原子 DDL 依赖的三个统一动作必须在一个事务里完成
MySQL 8.0 把 DDL 拆解为三步,且全部绑定到 InnoDB 事务:
- 更新数据字典表(如
mysql.tables、mysql.columns)→ 全部是 InnoDB 表 - 调用存储引擎接口(如
ha_innobase::create)→ InnoDB 层执行物理操作 - 写入 binlog DDL event → 由 server 层统一控制时机
只要任意一步失败,整个事务 rollback,对外表现为“没发生过”。这要求所有元数据载体必须支持 ACID —— MyISAM 不满足,所以被踢出系统表体系。
你还能在 8.0 里创建 MyISAM 表吗?能,但别用在系统层
MySQL 8.0 默认禁用 MyISAM 插件,但可通过 mysqld --plugin-load-add=ha_myisam.so 手动加载(不推荐)。不过即使加载成功:
-
CREATE TABLE t1 (...) ENGINE=MyISAM仍可执行(用户表层面兼容) -
mysql库下的任何表都不再允许用 MyISAM,强行指定会报错ERROR 1814 (HY000): Tablespace has been discarded或拒绝创建 - 像
CREATE VIEW、CREATE PROCEDURE这类非表对象 DDL,其元数据全存于mysql.component、mysql.proc等 InnoDB 表中,与引擎无关
真正被“废弃”的,从来不是 MyISAM 引擎本身,而是它在元数据管理链条中的历史角色 —— 那个分散、脆弱、无法回滚的旧范式。
迁移时最容易忽略的点:备份与权限校验逻辑
很多 DBA 升级后遇到问题,不是因为 DDL 失败,而是因为旧脚本假设了 MyISAM 系统表行为:
- 用
SELECT * FROM mysql.user WHERE engine='MyISAM'做判断 → 在 8.0 返回空,因engine列已从mysql.user移除 - 用
mysqldump --no-create-info mysql备份系统库 → 8.0 下可能漏掉部分动态权限视图(如role_edges),因其底层是基于数据字典的虚拟表 - 自定义监控脚本依赖
information_schema.TABLES.ENGINE = 'MyISAM'查系统表 → 8.0 中所有mysql表的ENGINE都是InnoDB,该条件永远为 false
这些细节不报错,但会让自动化流程静默失效 —— 它们才是升级后最常踩的坑。


















