• 售前

  • 售后

热门帖子
入门百科

MySQL8.0新特性之支持原子DDL语句

[复制链接]
紫色爱玫瑰咎 显示全部楼层 发表于 2021-10-26 14:06:30 |阅读模式 打印 上一主题 下一主题
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如果定名表不存在,而且未进行任何更改(无论存储引擎怎样),则会失败并表现错误。如下所示:
  1. mysql> CREATE TABLE t1 (c1 INT);
  2. mysql> DROP TABLE t1, t2;
  3. ERROR 1051 (42S02): Unknown table 'test.t2'
  4. mysql> SHOW TABLES;
  5. +----------------+
  6. | Tables_in_test |
  7. +----------------+
  8. | t1    |
  9. +----------------+
复制代码
在引入原子DDL之前, DROP TABLE虽然会报错误表不存在,但是存在的表会被实行成功,如下:
  1. mysql> CREATE TABLE t1 (c1 INT);
  2. mysql> DROP TABLE t1, t2;
  3. ERROR 1051 (42S02): Unknown table 'test.t2'
  4. mysql> SHOW TABLES;
  5. 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语句失败,因为定名视图不存在,如下:
  1. mysql> CREATE VIEW test.viewA AS SELECT * FROM t;
  2. mysql> DROP VIEW test.viewA, test.viewB;
  3. ERROR 1051 (42S02): Unknown table 'test.viewB'
  4. mysql> SHOW FULL TABLES IN test WHERE TABLE_TYPE LIKE 'VIEW';
  5. +----------------+------------+
  6. | Tables_in_test | Table_type |
  7. +----------------+------------+
  8. | viewA   | VIEW  |
  9. +----------------+------------+
复制代码
在引入原子DDL之前, 使用DROP VIEW删除视图会报错,但是存在的视图会被成功删除:
  1. mysql> CREATE VIEW test.viewA AS SELECT * FROM t;
  2. mysql> DROP VIEW test.viewA, test.viewB;
  3. ERROR 1051 (42S02): Unknown table 'test.viewB'
  4. mysql> SHOW FULL TABLES IN test WHERE TABLE_TYPE LIKE 'VIEW';
  5. Empty set (0.00 sec)
复制代码
注意:
   由于活动的这种厘革,DROP VIEW在MySQL 5.7主服务器上的部分完成 操作在MySQL 8.0从服务器上复制时会失败。要克制此故障环境,请在DROP VIEW语句中使用IF EXISTS语法以防止对不存在的视图发生错误。
3.6、不再允许部分实行帐户管理声明。帐户管理语句对所有定名用户成功或回滚,如果发生错误则无效。在早期的MySQL版本中,为多个用户定名的帐户管理语句大概对某些用户成功,而对其他用户则失败。
如下:其中第二个CREATE USER 语句返回错误但失败,因为它无法对所有定名用户成功。
  1. mysql> CREATE USER userA;
  2. mysql> CREATE USER userA, userB;
  3. ERROR 1396 (HY000): Operation CREATE USER failed for 'userA'@'%'
  4. mysql> SELECT User FROM mysql.user WHERE User LIKE 'user%';
  5. +-------+
  6. | User |
  7. +-------+
  8. | userA |
  9. +-------+
复制代码
在引入原子DDL之前,第二个 使用CREATE USER语句创建用户会返回一个错误,但是不存在的用户会成功创建,:
  1. mysql> CREATE USER userA;
  2. mysql> CREATE USER userA, userB;
  3. ERROR 1396 (HY000): Operation CREATE USER failed for 'userA'@'%'
  4. mysql> SELECT User FROM mysql.user WHERE User LIKE 'user%';
  5. +-------+
  6. | User |
  7. +-------+
  8. | userA |
  9. | userB |
  10. +-------+
复制代码
注意:
   由于活动的这种厘革,MySQL 5.7主服务器上部分会成功实行,会在MySQL 8.0从服务器上复制时失败。要克制此故障环境,请在创建用户的命令中使用IF EXISTS或 IF NOT EXISTS语法,以防止与定名用户相干的错误。
4、存储引擎支持:现在只有innodb存储引擎支持原子DDL

   现在,只有InnoDB存储引擎支持原子DDL。不支持原子DDL的存储引擎免于DDL原子性。涉及宽免存储引擎的DDL操作仍然可以或许引入操作中断或仅部分完成时大概发生的不划一。
   要支持重做和回滚DDL操作, InnoDB请将DDL日志写入 mysql.innodb_ddl_log表,该表是驻留在mysql.ibd数据字典表空间中的隐藏数据字典表 。
要mysql.innodb_ddl_log在DDL操作期间检察写入表的DDL日志 ,请启用 innodb_print_ddl_logs 配置选项。
注意:

mysql.innodb_ddl_log无论innodb_flush_log_at_trx_commit 设置多少,对表的 更改的重做日志 都会立即革新到磁盘 。立即革新重做日志可以克制DDL操作修改数据文件的环境,但是mysql.innodb_ddl_log由这些操作产生的对表的更改的重做日志 不会长期生存到磁盘。这种环境大概会在回滚或规复期间导致错误。
InnoDB存储引擎分阶段实行DDL操作。DDL操作 ALTER TABLE可以在Commit阶段之前多次实行 Prepare和Perform阶段:
准备:创建所需对象并将DDL日志写入 mysql.innodb_ddl_log表中。DDL日志定义了怎样前滚和回滚DDL操作。
实行:实行DDL操作。例如,为CREATE TABLE操作实行创建例程。
提交:更新数据字典并提交数据字典事件。
Post-DDL:重播并从mysql.innodb_ddl_log表中删除DDL日志。为了确保可以安全地实行回滚而不引入不划一性,在最后阶段实行文件操作,例如重定名或删除数据文件。这一阶段还从删除的动态元数据 mysql.innodb_dynamic_metadata的数据字典表DROP TABLE,TRUNCATE TABLE和该重建表其他DDL操作。
注意:
  无论事件是提交照旧回滚, DDL日志都会在Post-DDL阶段重播并从表中删除 。mysql.innodb_ddl_log如果服务器在DDL操作期间停息,则DDL日志应仅保留在表中。在这种环境下,DDL日志将在规复后重播并删除。
  在规复环境下,可以在重新启动服务器时提交或回滚DDL事件。如果在重做日志和二进制日志中存在在DDL操作的提交阶段期间实行的数据字典事件,则 该操作被视为成功而且前滚。否则,在InnoDB重放数据字典重做日志时回滚不完备的数据字典事件 ,并回滚DDL事件。
5、检察DDL日志:
   InnoDB将DDL日志写入 mysql.innodb_ddl_log表以支持重做和回滚DDL操作。该 mysql.innodb_ddl_log表是隐藏在mysql.ibd数据字典表空间中的隐藏数据字典表 。与其他隐藏数据字典表一样,mysql.innodb_ddl_log在非调试版本的MySQL中无法直接访问该 表。

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作