简介
MySQL8.0 开始支持原子 DDL(atomic DDL), 数据字典的更新, 存储引擎操作, 写二进制日志结合成了一个事务. 在没有原子 DDL 之前, DROP TABLE test1,test2; 如遇到 server crash, 可能会有 test1 被 drop 了, test2 没有被 drop 掉. 下面来看下在 MySQL8.0 之前和 MySQL8.0 数据字典的区别
在 MySQL8.0 之前, Data Dictionary 除了存在与. FRM, .TRG, .OPT 文件外, 还存在于系统表中 (MyISAM 非事务引擎表中), 在 MySQL8.0 ,Data Dictionary 全部存在于 Data Dictionary Storage Engine(即 InnoDB 表中), 这使 crash recovery 维持原子性成为了可能
存储引擎支持
目前, 只有 InnoDB 存储引擎支持原子 DDL, 为了实现原子 DDL,Innodb 要写 DDL logs 到 mysql.innodb_ddl_log 表, 这是一个隐藏在 mysql.ibd 数据字典表空间里的数据字典表. 要看 mysql.innodb_ddl_log 中的内容, 需要
- SET GLOBAL LOG_ERROR_VERBOSITY=3;(MySQL 8.0 默认为 2,error log 记录 Errors and warnings, 不记录 notes)
- SET GLOBAL innodb_print_ddl_logs=1;
- CREATE TABLE t1 (c1 INT) ENGINE = InnoDB;
查看 error log
- [Note] [MY-011066] InnoDB: DDL log insert : [DDL record: DELETE SPACE, id=30, thread_id=25, space_id=9, old_file_path=./test/t1.ibd]
- [Note] [MY-011066] InnoDB: DDL log delete : by id 30
- [Note] [MY-011066] InnoDB: DDL log insert : [DDL record: REMOVE CACHE, id=31, thread_id=25, table_id=1066, new_file_path=test/t1]
- [Note] [MY-011066] InnoDB: DDL log delete : by id 31
- [Note] [MY-011066] InnoDB: DDL log insert : [DDL record: FREE, id=32, thread_id=25, space_id=9, index_id=143, page_no=4]
- [Note] [MY-011066] InnoDB: DDL log delete : by id 32
- [Note] [MY-011066] InnoDB: DDL log post ddl : begin for thread id : 25
- [Note] [MY-011066] InnoDB: DDL log post ddl : end for thread id : 25
原子 DDL 操作步骤
1. 准备: 创建所需的对象并将 DDL 日志写入 mysql.innodb_ddl_log 表中. DDL 日志定义了如何前滚和回滚 DDL 操作.
2. 执行: 执行 DDL 操作. 例如, 为 CREATE TABLE 操作执行创建.
3. 提交: 更新数据字典并提交数据字典事务.
4.Post-DDL: 重播并从 mysql.innodb_ddl_log 表格中删除 DDL 日志. 为确保回滚可以安全执行而不引入不一致性, 在此最后阶段执行文件操作 (如重命名或删除数据文件). 这一阶段还从 mysql.innodb_dynamic_metadata 的数据字典表删除的动态元数据为了 DROP TABLE,TRUNCATE 和其它重建表的 DDL 操作.
无论事务是提交还是回滚, DDL 日志都会 mysql.innodb_ddl_log 在 Post-DDL 阶段重播并从表中删除 .mysql.innodb_ddl_log 如果服务器在 DDL 操作期间暂停, DDL 日志应该只保留在表中. 在这种情况下, DDL 日志会在恢复后重播并删除.
在恢复情况下, 当服务器重新启动时, 可能会提交或回退 DDL 事务. 如果在重做日志和二进制日志中存在 DDL 操作的提交阶段期间执行的数据字典事务, 则该操作被认为是成功的并且被前滚. 否则, 在 InnoDB 重放数据字典重做日志时回滚不完整的数据字典事务 , 并且回滚 DDL 事务.
原子 DDL 支持类型
DROP TABLES , all tables dropped or none
DROP SCHEMA, all entities in the schema are dropped, or none
Note that atomic DDL statements will be rolled back or committed even in
case of crash, e.g. RENAME TABLES
- CREATE TABLE would be successfully committed or rolled back (no orphan
- ibd left)
TRUNCATE TABLE (including InnoDB tables with FTS AUX tables) would be
successfully committed or rolled back
RENAME TABLES, all or none
ALTER TABLE successful or not done
示例
结论
在 MySQL8.0 之前, alter table 操作在 server crash 的情况下, 会遗留. frm,.ibd 文件. MySQL8.0 能实现原子 DDL(包括 DROP TABLE, DROP SCHEMA, CREATE TABLE, TRUNCATE TABLE, ALTER TABLE),alter table 操作, 在 server crash 的情况下, 不会遗留. frm,.ibd 临时文件. 让我们一起期待 MySQL8.0 GA 的到来吧!
参考:
- https://www.youtube.com/watch?v=jM53hSU9L70
- https://dev.mysql.com/doc/refman/8.0/en/atomic-ddl.html
来源: https://www.cnblogs.com/YangJiaXin/p/8776915.html