mysql 8.0 系统表强制使用 innodb 是因 myisam 崩溃后无法保证权限数据一致性,导致实例失去访问控制;权限变更需事务支持,myisam 不支持原子性;主从复制下 myisam 权限表失效;小表也不容忽视,myisam 已被官方弃用。

MySQL 8.0 系统表强制用 InnoDB 是因为崩溃恢复不可妥协
不是“为了更好”,而是“不换就崩”。MySQL 8.0 所有系统表(mysql.user、mysql.db、mysql.tables_priv 等)全部切换为 InnoDB,根本原因是:MyISAM 在异常宕机后无法保证权限数据一致性。一旦 mysqld crash,MyISAM 系统表大概率报 Table is marked as crashed,而 REPAIR TABLE 在 8.0+ 中已被弱化,修复成功率极低——此时连 SELECT USER() 都可能失败,整个实例失去访问控制能力。
权限变更必须支持事务,MyISAM 做不到
MySQL 8.0 引入了角色(CREATE ROLE)、动态权限(如 BACKUP_ADMIN)、可选的密码历史策略等,这些操作天然需要原子性。例如执行 GRANT SELECT ON db.* TO 'u'@'%'; GRANT INSERT ON db.* TO 'u'@'%';,若中途崩溃,MyISAM 可能只写入一条权限记录,造成权限状态撕裂;而 InnoDB 通过 undo log 和 redo log 保证整组 DCL 操作要么全生效、要么全回滚。你查 information_schema.role_table_grants 得到的结果,背后就是事务一致的快照。
主从复制场景下 MyISAM 权限表直接失效
MySQL 8.0 默认 binlog_format=ROW,但 MyISAM 不支持行格式日志,实际退化为 STATEMENT 模式。这导致:
-
NOW()、UUID()类函数在主从生成不同值,mysql.proxies_priv表中时间戳或 token 字段主从不一致 - 高可用工具(如 Orchestrator、MHA)依赖
SHOW SLAVE STATUS和performance_schema.replication_applier_status_by_coordinator判断同步位点,而这些表本身是 InnoDB,若权限表仍是 MyISAM,主从元数据层已不统一 - 集群自动故障转移时,新主库启动过程中若发现
mysql库含 MyISAM 表,部分版本会直接拒绝加载(已有测试报告在 8.0.33+ 出现ER_UNKNOWN_STORAGE_ENGINE报错)
别信“小表不用动”,权限表恰恰最不能赌
有人觉得 mysql.user 才几百行,用 MyISAM “省资源”。但现实是:权限表是 MySQL 启动时最先加载、最后释放的系统表,任何引擎不一致都会触发校验链路中断。官方文档里 MyISAM 关键词在 8.0+ 手册中仅出现在 Deprecated Features 章节,且 mysql_upgrade 工具自 8.0.33 起默认跳过 MyISAM 表检查——这不是疏忽,是明确告诉你:它已不在运维保障范围内。线上环境只要还留一个 MyISAM 权限表,下次主从切换或滚动重启,就可能卡在 Waiting for table metadata lock 上动弹不得。











