详谈 MySQL 8.0 原子 DDL 原理

柯煜昌 青云科技研发顾问级工程师 目前从事 RadonDB 容器化研发,华中科技大学研究生毕业,有多年的数据库内核开发经验。

文章字数 3800+,阅读时间 15 分钟

背景

MySQL 5.7 的字典信息保存在非事务表中,并且存放在不同的文件中(.FRM,.PAR,.OPT,.TRN,.TRG 等)。所有 DDL 操作都不是 Crash Safe,而且对于组合 DDL(ALTER 多个表)会出现有的成功有的失败的情况,而不是总体失败。这样主从复制就出现了问题,也导致基于复制的高可用系统不再安全。

MySQL 8.0 推出新特性 - 原子 DDL,解决了以上的问题。

什么是原子 DDL?

DDL 是指数据定义语言(Data Definition Language),负责数据结构的定义与数据对象的定义。原子 DDL 是指一个 DDL 操作是不可分割的,要么全成功要么全失败。

有哪些限制?

MySQL 8.0 只有 InnoDB 存储引擎支持原子 DDL。

支持语句:数据库、表空间、表、索引的 CREATE、ALTER 以及 DROP 语句,以及 TRUNCATE TABLE 语句。

MySQL 8.0 系统表均以 InnoDB 存储引擎存储,涉及到字典对象的均支持原子 DDL。

支持的语句:存储过程、触发器、视图以及用户定义函数(UDF)的 CREATE 和 DROP 、ALTER 操作,用户和角色的 CREATE、ALTER、DROP 语句,以及适用的 RENAME 语句,以及 GRANT 和 REVOKE 语句。

不支持的语句:

  • INSTALL PLUGIN、UNINSTALL PLUGIN
  • INSTALL COMPONENT、UNINSTALL COMPONENT
  • REATE SERVER、ALTER SERVER、DROP SERVER

实现原理是什么?

首先,8.0 将字典信息存放到事务引擎的系统表(InnoDB 存储引擎)中。这样 DDL 操作转变成一组对系统表的 DML 操作,从而失败后可以依据事务引擎自身的事务回滚保证系统表的原子性。

似乎 DDL 原子性就此就可以完成,但实际上并没有这么简单。首先字典信息不光是系统表,还有一组字典缓存,如:

  • Table Share 缓存
  • DD 缓存
  • InnoDB 中的 dict

此外,字典信息只是数据库对象的元数据,DDL 操作不光要修改字典信息,还要实实在在的操作对象,以及对象本身在内存中缓存。

  • 表空间
  • Dynamic meta
  • Btree
  • ibd 文件
  • buffer pool 中表空间的 page 页

此外,binlog 也要考虑 DDL 失败的情况。

因此,原子 DDL 在处理 DDL 失败的时候,不光是直接回滚系统表的数据,而且也要保证内存缓存,数据库对象也能回滚到一致状态。

实现细节

为了解决 DDL 失败情况中数据库对象的回滚,8.0 引入了系统表 DDL_LOG。该表在 mysql 库中。不可见,也不能人为操作。如果想了解该表的结果,先编译一个 debug 版的 MySQL:

SET SESSION debug='+d,skip_dd_table_access_check';
show create table  mysql.innodb_ddl_log;

可以看到如下表结构:

CREATE TABLE `innodb_ddl_log` (
  `id` bigint unsigned NOT NULL AUTO_INCREMENT,
  `thread_id` bigint unsigned NOT NULL,
  `type` int unsigned NOT NULL,
  `space_id` int unsigned DEFAULT NULL,
  `page_no` int unsigned DEFAULT NULL,
  `index_id` bigint unsigned DEFAULT NULL,
  `table_id
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值