mysql 8.0 ddl原子化_MySQL8.0 DDL原子性特性

MySQL 8.0引入了DDL的原子性特性,通过统一数据字典DD和DDL_LOG机制确保DDL操作的原子性。在DD基础上,将dd数据字典修改、引擎层修改和写binlog作为一个事务处理,利用事务原子性保证DDL操作的完整性。DDL操作如create table、drop table等在异常情况下可通过DDL_LOG的日志回放确保数据一致性,防止元数据不一致问题。
摘要由CSDN通过智能技术生成

1. DDL原子性概述

8.0之前并没有统一的数据字典dd,server层和引擎层各有一套元数据,sever层的元数据包括(.frm,.opt,.par,.trg等),用于存储表定义,分区表定义,触发器定义等信息;innodb层也有自己一套元数据,包括表信息,索引信息等,这两套元数据并没有机制保证一致性,这就导致了在异常情况下可能存在元数据不一致问题,一种典型场景下,删表操作,sever层的frm已经成功删除了,但引擎层数据字典并没有更新,导致再建重名表失败的问题。同样的,比如drop table t1,t2;可能出现只删除了t1,而t2仍然存在等问题。

8.0的一个重要工作是将数据字典统一,独立了DD(数据字典)模块,废弃了server层的元数据,将innodb的元数据抽象出一条DD接口供server层和innnodb层公用。在DD的基础上,引入了DDL的原子性特性,确保DDL操作要么全做,要么全不做的能力。实现这一套逻辑的关键点在于将ddl涉及到的修改,包括dd数据字典修改,引擎层的修改(创建文件,初始化tablespace,创建btree等)和写binlog作为一个“事务”,利用事务的原子性特点来保证ddl操作的原子性。

2.DDL原子性实现原理

实现原子性的关键在于确保dd数据字典修改,引擎层的修改和写binlog是一个事务。MySQL已有的XA事务机制能有效保证DML事务和binlog的一致性。而ddl数据字典也是通过innodb引擎存储,因此做到dd数据字典修改和binlog一致是容易的;那么还需要解决的一个问题是,dd数据字典和引擎层修改的一致性,引擎层的修改并不都是记redo的,比如创建文件,rename文件名,或者清理cache等,无法简单地通过XA机制解决问题,因此8.0还引入了一套DDL_LOG机制。具体而言,就是将不记redo的一些操作,通过记日志的方式写入到ddl_log表中,而这个表是innodb引擎表,通过保证ddl_log数据与dd数据字典修改达成一致,而最终解决dd数据字典修改,引擎层的修改和写binlog一致性问题。

3.DD引入前后对比

48cc08a3259e941816fcd80bef874338.png

7578c9691bdb0c5e3865e896556379b1.png                                ​​

4.DDL操作实现逻辑

引入ddl_log表后,ddl操作在原有的基础上有一些变化,主要有两点,一点是在执行ddl的过程中,会记录ddl操作到ddl_log表中;另一点是新增了一个post_ddl阶段,ddl事务提交后,做一些ddl的收尾动作,比如drop-table,真正的删除物理文件是在post-ddl阶段做的。post-ddl做的事情主要就是,读取ddl-log内容,进行回放执行。ddl操作类型如下:

enum class Log_Type : uint32_t {/** Smallest log type*/SMALLEST_LOG= 1,/** Drop an index tree*/FREE_TREE_LOG= 1,/** Delete a file*/DELETE_SPACE_LOG,/** Rename a file*/RENAME_SPACE_LOG,/** Drop the entry in innodb_dynamic_metadata*/DROP_LOG,/** Rename table in dict cache.*/RENAME_TABLE_LOG,/** Remove a table from dict cache*/REMOVE_CACHE_LOG,/** Alter Encrypt a tablespace*/ALTER_ENCRYPT_TABLESPACE_LOG,/** Biggest log type*/BIGGEST_LOG=ALTER_ENCRYPT_TABLESPACE_LOG

};

通过innodb_print_ddl_logs开关,可以看到ddl过程中写入到innodb_ddl_log表中的内容。下面会以几个典型的ddl操作产生的ddl_log来说明如何保证ddl的原子性。

4.1 create table

语句:create table dd_tt(id int primary key, c1 int);

[InnoDB] DDL log insert : [DDL record: DELETE SPACE, id=352, thread_id=23, space_id=71, old_file_path=./mysql/dd_tt.ibd]

[InnoDB] DDL log delete : 352

[InnoDB] DDL log insert : [DDL record: REMOVE CACHE, id=353, thread_id=23, table_id=1128, new_file_path=mysql/dd_tt]

[InnoDB] DDL log delete : 353

[InnoDB] DDL log insert : [DDL record: FREE, id=354, thread_id=23, space_id=71, index_id=231, page_no=4]

[InnoDB] DDL log delete : 354

[InnoDB] DDL log post ddl : begin for thread id : 23

[InnoDB] DDL log post ddl : end for thread id : 23

说明:

1.所有insert操作都是一个单独的事务,对应的逆向delete操作是整个ddl事务的一部分。

2

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值