mysql 8.0中innodb数据字典的核心变化是元数据统一存入innodb事务表,实现acid保障;mysql.tables等系统表被设为不可见,仅供内部ddl使用,对外通过information_schema视图访问。

MySQL 8.0 中 InnoDB 数据字典的核心变化是:元数据从分散、非事务性的文件和 MyISAM 表,统一收归为 InnoDB 引擎管理的事务表。 这不是小修小补,而是整个元数据生命周期(创建、修改、删除、崩溃恢复)都被纳入 ACID 保障范围。直接后果就是 DROP TABLE 不会只删一半,ALTER TABLE ADD COLUMN 不会留下结构错乱的残留状态。
为什么你查不到 mysql.tables 却必须知道它存在
MySQL 8.0 把 mysql.tables、mysql.columns、mysql.indexes 等全部设为“不可见系统表”——你不能 SELECT、DESCRIBE 或 DROP 它们,连 SHOW TABLES 都不显示。这不是 bug,是设计:
- 这些表只供 server 内部 DDL 流程使用,暴露给用户会破坏向后兼容性和升级弹性
- 所有对外查询都走
INFORMATION_SCHEMA视图,比如INFORMATION_SCHEMA.TABLES,它背后实时查的就是mysql.tables - 如果你硬要绕过视图直查(比如用调试工具),会触发权限拒绝或空结果,不是数据丢了,是被有意屏蔽
innodb_read_only=ON 为什么会让 ANALYZE TABLE 失败
以前 innodb_read_only 只锁 InnoDB 表的增删改;MySQL 8.0 后,它直接禁止所有引擎的 DDL 和部分 DML,因为这些操作都要更新数据字典表——而它们全在 mysql 库里,且全是 InnoDB 引擎:
-
ANALYZE TABLE会写入mysql.innodb_table_stats和mysql.innodb_index_stats,这两个表受innodb_read_only约束 -
ALTER TABLE ... ENGINE=MyISAM同样失败:改引擎需更新mysql.tables的engine字段,但该字段现在是 InnoDB 表里的行 - 连
CREATE TEMPORARY TABLE都可能受影响——如果临时表涉及字典缓存刷新逻辑
mysql.innodb_ddl_log 是什么,为什么你永远看不到它
mysql.innodb_ddl_log 是原子 DDL 的物理层保险丝,但它被彻底隐藏:没有 SHOW CREATE TABLE、不能 SELECT、无法 DESCRIBE。它的唯一使命是在崩溃后启动时自动扫描并执行补偿动作:
- 比如
RENAME TABLE t1 TO t2中,文件重命名成功但mysql.tables更新失败,InnoDB 启动时会读innodb_ddl_log,把新文件删掉、恢复旧名 - 这个日志只在 DDL 执行中写入,事务提交后立即清理,正常运行时为空
- 你无法手动干预它——既不能清空,也不能禁用,它是 crash recovery 的底层机制,不是配置项
真正容易被忽略的点是:数据字典的事务性不等于“永不失败”,而是“失败可回滚”。只要 DDL 没提交,就没人能看到中间态;但一旦提交,mysql.tables 和磁盘上 .ibd 文件的状态必然严格一致——这个一致性不再靠人肉校验,而是由 InnoDB 的 undo log 和 doublewrite buffer 保证。











