MySQL 8.0 之原子DDL

0    82    1

Tags:

👉 本文共约2327个字,系统预计阅读时间或需9分钟。

原子DDL

听到原子这个关键字大家是不是联想到事务的ACID的原子性?两者相似,事务/语句执行要么全部成功,要么全部失败。MySQL 8.0 之前的版本 DDL 是非原子性的,对于多条sql构成的ddl语句比如 rename table t1 to t1_bak,t2 to t2_bak;
执行过程中如果遇到系统异常crash,有可能出现表t1被rename,但是t2没有被rename的情况。出现该情况的原因就是MySQL不支持原子的DDL。

MySQL8.0 之前的数据字典结构图:

MySQL 8.0 之原子DDL

从图中我们可以看出, 元数据信息在存储于 .FRM .TRG .OPT文件系统,MyISAM引擎的系统表里,以及 Innodb存储引擎的系统表。分裂成多处这样的架构导致在系统异常的情况下很容易造成数据的不一致。

MySQL 8.0 的数据字典结构图:

MySQL 8.0 之原子DDL

从图中我们明显可以看出 Data Dictionary 全部存在于由InnoDB表构成的系统表中
Data Dictionary Table。当遇到 crash recovery的时候,系统可以安全的进行事务回滚,保障DDL语句的原子性。

说了这么多,我们动手实践一下 。

案例实践

对比 5.7 vs 8.0 的测试图

MySQL 5.7.22 DDL 操作 删除两个表,其中一个t2不存在。

MySQL 8.0 之原子DDL

MySQL 8.0.20 的原子性操作

MySQL 8.0 之原子DDL

MySQL 8.0 支持原子性,DDL 失败之后 t1 还在,但是5.7 版本中 t1 就被删除了。

原子DDL 操作步骤

InnoDB 存储引擎执行 DDL 时是分阶段进行的。比如 ALTER TABLE,可能会在执行提交阶段之前多次执行准备阶段和执行阶段的操作。

准备:创建所需的对象,并且将 DDL 日志写入 mysql.innodb_ddl_log 表中。
DDL 日志定义了如何前滚和回滚相应的 DDL 操作。

执行:执行 DDL 操作。例如,为 CREATE TABLE 执行创建操作。

提交:更数据字典并提交数据字典事务。

Post-DDL:重放并删除 mysql.innodb_ddl_log 表中的 DDL 日志。为了能够安全地执行回滚操作而不会导致不一致性,对于文件的操作,例如重命名数据文件或移动数据文件,放在这个最后的阶段执行。这个阶段还会为 DROP TABLE、TRUNCATE TABLE 以及其他重建表的 DDL 操作删除数据字典表 mysql.innodb_dynamic_metadata 中的动态元数据。

无论事务被提交还是回滚,在 Post-DDL 阶段都会重放并删除 mysql.innodb_ddl_log 表中的 DDL 日志。只有当服务器在执行 DDL 操作的过程中出现故障时,才会在 mysql.innodb_ddl_log 表中保留 DDL 日志。这种情况下,在服务器恢复之后执行 DDL 日志的重放和删除。

对于需要进行恢复的情况,服务器重启之后,可能执行 DDL 事务的提交,也可能执行事务的回滚。如果在提交阶段执行的数据字典事务已经记录在重做日志和二进制日志中,就会认为 DDL 操作已经成功,并且执行前滚操作。否则,当 InnoDB 重放数据字典重做日志的时候,将会回滚不完整的数据字典事务,并且回滚 DDL 事务。

查看 DDL 日志

为了支持 原子 DDL,InnoDB 在执行DDL 语句时将日志写入隐藏的数据字典表mysql.innodb_ddl_log中,该表存储在 mysql.ibd 数据字典表空间。所谓隐藏数据字典表,就是在不能以正常的方式直接访问,得在调试 debug模式下访问隐藏表。

各个字段的注释

id:每条 DDL 日志记录的唯一标识符。
thread_id:每个 DDL 日志记录都与一个 thread_id 相关联,用于重放和删除某个特定 DDL 事务的 DDL 日志。涉及多个数据文件操作的 DDL 事务将会生成多条 DDL 日志记录。
type:DDL 操作的类型。包括 FREE (删除一棵索引树)、DELETE(删除一个文件)、RENAME (重命名文件)或者 DROP(从数据字典表 mysql.innodb_dynamic_metadata 中删除元数据)。
space_id:表空间 ID.
page_no:包含分配信息的页面;例如,索引树的根页面。
index_id:索引 ID。
table_id:表 ID。
old_file_path:旧的表空间文件路径。用于创建或删除表空间文件的 DDL 操作;以及重命名表空间的 DDL 操作。
new_file_path:新的表空间文件路径。用于重命名表空间文件的 DDL 操作。

另外就是我们可以通过设置 innodb_print_ddl_logs=1log_error_verbosity=3 在MySQL 的 系统日志里面查看DDL log,比如我运行的MySQL 8.0是在docker中 ,使用 docker logs mysql8.0

MySQL 8.0 之原子DDL

日志表示 执行 create table t2 的ddl 日志过程。

MySQL 8.0 原子DDL 使用范围

支持的ddl范围

本人提供Oracle(OCP、OCM)、MySQL(OCP)、PostgreSQL(PGCA、PGCE、PGCM)等数据库的培训和考证业务,私聊QQ646634621或微信db_bao,谢谢!
MySQL 8.0 之原子DDL后续精彩内容已被小麦苗无情隐藏,请输入验证码解锁本站所有文章
验证码:
请关注本站微信公众号,回复“小麦苗博客”,获取验证码。在微信里搜索“DB宝”或者“www_xmmup_com”或者微信扫描右侧二维码都可以关注本站微信公众号。

标签:

Avatar photo

小麦苗

学习或考证,均可联系麦老师,请加微信db_bao或QQ646634621

您可能还喜欢...

发表回复

嘿,我是小麦,需要帮助随时找我哦
  • 18509239930
  • 个人微信

  • 麦老师QQ聊天
  • 个人邮箱
  • 点击加入QQ群
  • 个人微店

  • 回到顶部