MySQL 8.0开始支持原子数据定义语言(DDL)语句。此功能称为原子DDL。原子DDL语句将与DDL操作关联的数据字典更新,存储引擎操作和二进制日志写入组合到单个原子事务中。即使服务器在操作期间暂停,也会提交事务,并将适用的更改保留到数据字典,存储引擎和二进制日志,或者回滚事务。
通过在MySQL 8.0中引入MySQL数据字典,可以实现Atomic DDL。在早期的MySQL版本中,元数据存储在元数据文件,非事务性表和存储引擎特定的字典中,这需要中间提交。MySQL数据字典提供的集中式事务元数据存储消除了这一障碍,使得将DDL语句操作重组为原子事务成为可能。
官方文档:
https://dev.mysql.com/doc/refman/8.0/en/atomic-ddl.html
1、支持的DDL语句
原子DDL功能支持表和非表DDL语句。与表相关的DDL操作需要存储引擎支持,而非表DDL操作则不需要。目前,只有InnoDB存储引擎支持原子DDL。
①:受支持的表DDL语句包括 CREATE,ALTER和 DROP对数据库,表,表和索引,以及语句 TRUNCATE TABLE声明。
②:支持的非表DDL语句包括:
CREATE和DROP 语句,以及(如果适用)ALTER 存储程序,触发器,视图和用户定义函数(UDF)的语句。
账户管理语句: CREATE,ALTER, DROP,,如果适用, RENAME报表用户和角色,以及GRANT 和REVOKE报表。
1.1、原子DDL功能不支持以下语句:
①:涉及除存储引擎之外的存储引擎的与表相关的DDL语句InnoDB。
②:INSTALL PLUGIN和 UNINSTALL PLUGIN 陈述。
③:INSTALL COMPONENT和 UNINSTALL COMPONENT 陈述。
④:CREATE SERVER, ALTER SERVER和 DROP SERVER语句。
2、原子DDL特性:
①:元数据更新,二进制日志写入和存储引擎操作(如果适用)将合并为单个事务。
②:在DDL操作期间,SQL层没有中间提交。
③:在适用的情况下:
数据字典,程序,事件和UDF高速缓存的状态与DDL操作的状态一致,这意味着更新高速缓存以反映DDL操作是成功完成还是回滚。
DDL操作中涉及的存储引擎方法不执行中间提交,并且存储引擎将自身注册为DDL事务的一部分。
存储引擎支持DDL操作的重做和回滚,这在DDL操作的 Post-DDL阶段执行。
④:DDL操作的可见行为是原子的,这会更改某些DDL语句的行为
注意:
原子或其他DDL语句隐式结束当前会话中处于活动状态的任何事务,就好像您COMMIT在执行语句之前完成了一样。这意味着DDL语句不能在另一个事务中,在事务控制语句中执行 START TRANSACTION ... COMMIT,或者与同一事务中的其他语句结合使用。
3、DDL语句行为的变化
3.1、DROP TABLE:
如果所有命名表都使用原子DDL支持的存储引擎,则操作是完全原子的。该语句要么成功删除所有表,要么回滚。
DROP TABLE如果命名表不存在,并且未进行任何更改(无论存储引擎如何),则会失败并显示错误。如下所示:
mysql> CREATE TABLE t1 (c1 INT);
mysql> DROP TABLE t1, t2;
ERROR 1051 (42S02): Unknown table 'test.t2'
mysql> SHOW TABLES;
+----------------+
| Tables_in_test |
+----------------+
| t1 |
+----------------+
在引入原子DDL之前, DROP TABLE虽然会报错误表不存在,但是存在的表会被执行成功,如下:
mysql> CREATE TABLE t1 (c1 INT);
mysql> DROP TABLE t1, t2;
ERROR 1051 (42S02): Unknown table 'test.t2'
mysql> SHOW TABLES;
Empty set (0.00 sec)
注意:
由于行为的这种变化,DROP TABLE会在 MySQL 5.7主服务器上的部分完成 语句在MySQL 8.0从服务器上复制时失败。要避免此故障情形,请在DROP TABLE语句中使用IF EXISTS语法以防止对不存在的表发生错误
3.2、DROP DATABASE:
如果所有表都使用原子DDL支持的存储引擎,则为atomic。该语句要么成功删除所有对象,要么回滚。但是,从文件系统中删除数据库目录是最后一次,并且不是原子事务的一部分。如果由于文件系统错误或服务器暂停而导致数据库目录的删除失败, DROP DATABASE则不会回滚事务。
3.3、对于不使用原子DDL支持的存储引擎的表,表删除发生在原子 DROP TABLE或 DROP DATABASE事务之外。这样的表删除被单独写入二进制日志,这在中断DROP TABLE或 DROP DATABASE操作的情况下将存储引擎,数据字典和二进制日志之间的差异限制为最多一个表 。对于删除多个表的操作,不使用原子DDL支持的存储引擎的表将在执行之前删除。
3.4、CREATE TABLE, ALTER TABLE, RENAME TABLE, TRUNCATE TABLE, CREATE TABLESPACE,和 DROP TABLESPACE对使用原子DDL支持的存储引擎表执行的操作要么完全提交或如果服务器的操作时停止回滚。在早期的MySQL版本中,这些操作的中断可能会导致存储引擎,数据字典和二进制日志之间的差异,或留下孤立文件。RENAME TABLE如果所有命名表都使用原子DDL支持的存储引擎,则操作只是原子操作。
3.5、DROP VIEW:
如果命名视图不存在且未进行任何更改,则会失败。在此示例中演示了行为更改,其中 DROP VIEW语句失败,因为命名视图不存在,如下:
mysql> CREATE VIEW test.viewA AS SELECT * FROM t;
mysql> DROP VIEW test.viewA, test.viewB;
ERROR 1051 (42S02): Unknown table 'test.viewB'
mysql> SHOW FULL TABLES IN test WHERE TABLE_TYPE LIKE 'VIEW';
+----------------+------------+
| Tables_in_test | Table_type |
+----------------+------------+
| viewA | VIEW |
+----------------+------------+
在引入原子DDL之前, 使用DROP VIEW删除视图会报错,但是存在的视图会被成功删除:
mysql> CREATE VIEW test.viewA AS SELECT * FROM t;
mysql> DROP VIEW test.viewA, test.viewB;
ERROR 1051 (42S02): Unknown table 'test.viewB'
mysql> SHOW FULL TABLES IN test WHERE TABLE_TYPE LIKE 'VIEW';
Empty set (0.00 sec)
注意: