MySQL8.0新特性——支持原子DDL语句
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)
注意:
由于行为的这种变化,DROP VIEW在MySQL 5.7主服务器上的部分完成 操作在MySQL 8.0从服务器上复制时会失败。要避免此故障情形,请在DROP VIEW语句中使用IF EXISTS语法以防止对不存在的视图发生错误。
3.6、不再允许部分执行帐户管理声明。帐户管理语句对所有命名用户成功或回滚,如果发生错误则无效。在早期的MySQL版本中,为多个用户命名的帐户管理语句可能对某些用户成功,而对其他用户则失败。
如下:其中第二个CREATE USER 语句返回错误但失败,因为它无法对所有命名用户成功。
mysql> CREATE USER userA;
mysql> CREATE USER userA, userB;
ERROR 1396 (HY000): Operation CREATE USER failed for 'userA'@'%'
mysql> SELECT User FROM mysql.user WHERE User LIKE 'user%';
+-------+
| User |
+-------+
| userA |
+-------+
在引入原子DDL之前,第二个 使用CREATE USER语句创建用户会返回一个错误,但是不存在的用户会成功创建,:
mysql> CREATE USER userA;
mysql> CREATE USER userA, userB;
ERROR 1396 (HY000): Operation CREATE USER failed for 'userA'@'%'
mysql> SELECT User FROM mysql.user WHERE User LIKE 'user%';
+-------+
| User |
+-------+
| userA |
| userB |
+-------+
注意:
由于行为的这种变化,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中无法直接访问该 表。
MySQL8.0新特性——支持原子DDL语句的更多相关文章
- MySQL 8.0新特性之原子DDL
文章来源:爱可生云数据库 简介 MySQL8.0 开始支持原⼦ DDL(atomic DDL),数据字典的更新,存储引擎操作,写⼆进制日志结合成了一个事务.在没有原⼦DDL之前,DROP TABLE ...
- MySQL8新特性(1)--原子DDL
mysql 8支持原子ddl.一个原子DDL语句包含数据字典更新.存储引擎操作.二进制日志写,事务要么被提交,应用修改被持持久化到数据字典.存储引擎和二进制日志,或者被回滚. 原子ddl是随着mysq ...
- 跨时代的MySQL8.0新特性解读
目录 MySQL发展历程 MySQL8.0新特性 秒级加列 性能提升 文档数据库 SQL增强 共用表表达式(CTEs) 不可见索引(Invisible Indexes) 降序索引(Descending ...
- C# 9.0 新特性预览 - 顶级语句
C# 9.0 新特性预览 - 顶级语句 前言 随着 .NET 5 发布日期的日益临近,其对应的 C# 新版本已确定为 C# 9.0,其中新增加的特性(或语法糖)也已基本锁定,本系列文章将向大家展示它们 ...
- Mysql8.0新特性【详细版本】
1. 账户与安全 用户创建与授权 之前:创建用户并授权 1 grant all privileges on *.* to 'myuser'@'%' identified by '3edc#EDC'; ...
- MySQL8.0新特性实验1
Server层,选项持久化 mysql> show variables like '%max_connections%';+------------------------+-------+| ...
- 深入解读MySQL8.0 新特性 :Crash Safe DDL
前言 在MySQL8.0之前的版本中,由于架构的原因,mysql在server层使用统一的frm文件来存储表元数据信息,这个信息能够被不同的存储引擎识别.而实际上innodb本身也存储有元数据信息.这 ...
- MySQL-08 MySQL8.0新特性
性能 MySQL 8.0 在一定的用户访问条件下,速度要比 MySQL 5.7 快 2 倍.MySQL 8.0 在以下方面带来了更好的性能:读/写工作负载.IO 密集型工作负载.以及高竞争(" ...
- MySQL8.0 新特性 Hash Join
概述&背景 MySQL一直被人诟病没有实现HashJoin,最新发布的8.0.18已经带上了这个功能,令人欣喜.有时候在想,MySQL为什么一直不支持HashJoin呢?我想可能是因为MySQ ...
随机推荐
- dubbo实现原理简单介绍
一.什么是dubbo Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解耦合(或者最大限度地松耦合).从服务模型的角度来看, ...
- Shell脚本中获取select值
最近做一个数据清理,根据行号清理,所以需要查出这个行的最大最小值出来进行删除,如果靠手动每次去查,太麻烦所以就用在sh脚本当中执行SELECT语句,并将结果赋值给一个变量. sh脚本如下 #! /bi ...
- spring的7个模块
Spring 是一个开源框架,是为了解决企业应用程序开发复杂性而创建的.框架的主要优势之一就是其分层架构,分层架构允许您选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架. Spring ...
- Java 8 异常该进
try-with-resources 这个特性是在JDK7中出现的,我们在之前操作一个流对象的时候大概是这样的: try { // 使用流对象 stream.read(); stream.write( ...
- CSS3 :nth-child() 选择器---挖坑
E:nth-child(n) 语法: E:nth-child(n) { sRules } 说明: 匹配父元素的第n个子元素E,假设该子元素不是E,则选择符无效.(也就是说,会检查从body开始的每个元 ...
- 点击<a>页面跳转解决办法/跨域请求,JSONP
有些时候做的东西刚好要用到链接,但又不需要去链接,只需要对onclick事件进行处理,但它却这样子写 <a href="#" onclick="gettext()& ...
- nodejs模板加载的问题
JADE模板:http://jumplink.github.io/jade2html2jade/ HTML转JADE,跟imooc上一步步来就搞定了 直接加载HTML静态资源: var express ...
- Spider与OpenPyXL的结合
OpenPyXL的API文档 1.OpenPyXL基础操作 引入Workbook这个类,然后调用 from openpyxl import Workbook wb = Workbook() 通过ope ...
- Hibernate Annotation _List/Map
// Student.java 实体类 package com.tao.pojo; import java.util.List; public class Student { private int ...
- 【游戏开发】小白学Lua——从Lua查找表元素的过程看元表、元方法
引言 在上篇博客中,我们简单地学习了一下Lua的基本语法.其实在Lua中有一个还有一个叫元表的概念,不得不着重地探讨一下.元表在实际地开发中,也是会被极大程度地所使用到.本篇博客,就让我们从Lua查找 ...