【MySQL精通之路】MySQL8.0新增功能-原子DDL语句支持

news2024/11/16 7:45:46

太长不看系列:

本文一句话总结,MySQL8.0支持多条DDL语句执行时的原子性了(仅限Innodb)

本文属于下面这篇博客的子博客:

【MySQL精通之路】MySQL8.0官方文档-新增功能

1.意义描述

MySQL 8.0支持原子数据定义语言(DDL)语句。此功能被称为原子DDL。原子DDL语句将与DDL操作相关联的数据字典更新存储引擎操作二进制日志写入合并为单个原子操作。该操作要么被提交,并将适用的更改持久化到数据字典、存储引擎和二进制日志中,要么被回滚,即使服务器在操作过程中停止。

注意:

原子DDL不是事务DDL。DDL语句,无论是原子语句还是其他语句,都会隐式地结束当前会话中活动的任何事务,就好像在执行该语句之前执行了COMMIT一样。这意味着DDL语句不能在另一个事务中执行,也不能在事务控制语句(如START transaction…)中执行。。。COMMIT,或与同一事务中的其他语句组合。

博主PS:

DDL(data definition language)是数据定义语言:DDL比DML要多,主要的命令有CREATE、ALTER、DROP

通过在MySQL 8.0中引入MySQL数据字典Atomic DDL成为可能。在早期的MySQL版本中,元数据存储在元数据文件、非事务表和特定于存储引擎的字典中,这就需要进行中间提交。MySQL数据字典提供的集中式、事务性元数据存储消除了这一障碍,使DDL语句操作可以重新构造为原子操作。

博主PS:相信从官方文档博客过来的朋友已经详读过下面这篇关于数据字典的博客了,看过的朋友应该比较容易理解上面这段话,需要数据字典前置知识

【MySQL精通之路】MySQL8.0官方文档-数据字典-CSDN博客

原子DDL功能在本节的以下主题下进行了描述:

2.功能描述

2.1 支持的DDL语句

原子DDL功能同时支持表和非表DDL语句与表相关的DDL操作需要存储引擎支持而非表DDL操作则不需要。目前,只有InnoDB存储引擎支持原子DDL

支持的表DDL语句:

数据库表空间索引CREATEALTERDROP语句,以及 TRUNCATE TABLETRUNCATE TABLETRUNCATE TABLE语句。

支持的非表DDL语句包括:
CREATE和DROP语句,以及存储程序、触发器、视图和可加载函数的ALTER语句(如果适用)。

帐户管理语句:

CREATE、ALTER、DROP,以及用户和角色的RENAME语句(如果适用),以及GRANT和REVOKE语句。


原子DDL功能不支持以下语句:

- 涉及InnoDB以外的存储引擎的表相关DDL语句。
- INSTALL PLUGIN和UNINSTALL PLUGING语句。
- INSTALL COMPONENT和UNINSTALL COMPONMENT语句。
- CREATE SERVER、ALTER SERVER和DROP SERVER语句。


2.2 原子DDL特性

原子DDL语句的特征包括以下内容:

元数据更新、二进制日志写入和存储引擎操作(如果适用)组合为一个原子操作。在DDL操作期间,SQL层没有中间提交。

适用:
数据字典例程事件可加载函数缓存的状态与DDL操作的状态一致,这意味着缓存会更新以反映DDL操作是否成功完成或回滚。

DDL操作中涉及的存储引擎方法不执行中间提交,存储引擎将自己注册为DDL操作的一部分。
存储引擎支持DDL操作的重做和回滚,这是在DDL操作的后DDL阶段执行的。

DDL操作的可见行为是原子行为,它会更改某些DDL语句的行为。请参阅DDL语句行为中的更改。

2.3 DDL语句行为的更改

本节介绍由于引入原子DDL支持而导致的DDL语句行为的变化

2.3.1 DROP TABLE

如果所有命名表都使用原子DDL支持的存储引擎,则DROP TABLE操作是完全原子的。该语句要么成功删除所有表,要么回滚。

如果命名表不存在,并且不进行任何更改(无论存储引擎如何),则DROP TABLE将失败并返回错误。下面的示例演示了这种行为变化,其中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)

博主PS:这块好理解,就是没有DDL原子语义之前,你执行一条需要操作两个表的sql时,就算有个表因为不存在而失败了,对另外一个表的操作也会成功,可以看见示例中,虽然t2

表不存在报错了,t1表也被删除了。这种就是非原子性的。

注意:
由于此行为变化,在MySQL 5.7复制源服务器上部分完成的DROP TABLE语句在MySQL 8.0复制副本上复制时失败。为了避免这种失败情况,请在DROP TABLE语句中使用IF EXISTS语法,以防止不存在的表出现错误

2.3.2 DROP DATABASE

如果所有表都使用原子DDL支持的存储引擎,那么DROP DATABASE就是原子数据库。该语句要么成功删除所有对象,要么回滚。但是,从文件系统中删除数据库目录是最后一次,并且不是原子操作的一部分。如果由于文件系统错误或服务器停止而导致数据库目录删除失败,则DROP database事务不会回滚

2.3.2 DROP DATABASE

对于使用不支持DDL的原子存储引擎的表,表删除发生在原子DROP table或DROP DATABASE事务之外。这样的表删除被单独写入二进制日志(Binlog),这将在DROP table或DROP DATABASE操作中断的情况下,存储引擎、数据字典和二进制日志之间的数据差异限制为最多一个表。对于删除多个表的操作,使用不支持DDL原子存储引擎的表会先删除,然后再删除支持的。

2.4 存储引擎支持

使用原子DDL支持的存储引擎的表的语句:

2.4.1 孤立文件

CREATE TABLE、ALTER TABLE、RENAME TABLE、TRUNCATE TABLE、CREATE TABLESPACE和DROP TABLESPACE操作将完全提交,或者在服务器运行期间停止时回滚。

在早期的MySQL版本中,这些操作的中断可能会导致存储引擎、数据字典和二进制日志之间的差异,或者留下孤立文件。

如果所有表都使用原子DDL支持的存储引擎,RENAME TABLE操作才为原子操作。

2.4.2 基于行的复制

从MySQL 8.0.21开始,在支持原子DDL的存储引擎上,CREATE TABLE....SELECT 当使用基于行的复制时,SELECT语句作为一个事务记录在二进制日志中

以前,它被记录为两个事务,一个用于创建表,另一个用于插入数据。两个事务之间的服务器故障或插入数据时的服务器故障可能导致空表的复制。

随着原子DDL支持的引入,CREATE TABLE...SELECT语句现在对于基于行的复制是安全的,并且允许与基于GTID的复制一起使用。

2.4.3 外键约束

在同时支持原子DDL外键约束的存储引擎上,使用基于行的复制时的SELECT语句不允许在CREATE TABLE....SELECT 中创建外键。可以使用ALTER TABLE添加外键约束。

当CREATE TABLE...SELECT作为一个原子操作应用,在插入数据时会在表上保留元数据锁从而在操作期间防止对表的并发访问

2.4.4 视图

如果命名视图不存在并且未进行任何更改,则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       |
+----------------+------------+

 博主PS:这里和上文提到的对多个表的DDL操作会回滚一个道理

在引入原子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)

注意:
由于此行为变化,在MySQL 5.7复制源服务器上部分完成的DROP VIEW操作在MySQL 8.0复制副本上复制时失败。为了避免这种失败情况,请在DROP VIEW语句中使用IF EXISTS语法,以防止不存在的视图发生错误。

不再允许部分执行帐户管理报表。帐户管理语句要么对所有命名用户成功,要么回滚,如果发生错误则无效。在早期的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语法,以防止出现与命名用户相关的错误。

目前,只有InnoDB存储引擎支持原子DDL。不支持原子DDL的存储引擎不受DDL原子性的约束。涉及不支持原子DDL的存储引擎的DDL操作仍然能够引入操作中断或仅部分完成时可能出现的不一致。

2.4.5 innodb_ddl_log

为了支持DDL操作的重做和回滚,InnoDB将DDL日志写入 mysql.innodb_ddl_log 表,这是一个隐藏的数据字典表,位于mysql.ibd数据字典表空间中。

要查看在DDL操作期间写入mysql.innodb_DDL_log表的DDL日志,请启用innodb_print_ddl_logs配置选项。有关详细信息,请参阅查看DDL日志。

注意:
无论innodb_flush_log_at_trx_commit设置如何,mysql.innodb_ddl_log表更改的重做日志都会立即刷新到磁盘。立即刷新redolog可以避免DDL操作修改数据文件,但这些操作导致的对mysql.innodb_ddl_log表的更改的重做日志不会持久化到磁盘。这种情况可能会在回滚或恢复过程中导致错误

2.4.6 执行DDL操作

InnoDB存储引擎分阶段执行DDL操作。DDL操作(如ALTER TABLE)可以在提交阶段之前多次执行准备和执行阶段。

准备:创建所需的对象,并将DDL日志写入mysql.innodb_ddl_log表。DDL日志定义了如何前滚和后滚DDL操作。

执行:执行DDL操作。例如,为CREATE TABLE操作执行创建例程

提交:更新数据字典提交数据字典事务

发布DDL:从mysql.innodb_ddl_log表中回放并删除DDL日志。为了确保在不引入不一致的情况下安全地执行回滚,在最后阶段执行文件操作,如重命名或删除数据文件。此阶段还从mysql.innodb_dynamic_metadata数据字典表中删除DROP table、TRUNCATE table和其他重建该表的DDL操作的动态元数据

在后DDL阶段,无论DDL操作是提交还是回滚,都会重播DDL日志,并从mysql.innodb_ddl_log表中删除DDL日志。如果服务器在DDL操作期间停止,则DDL日志应仅保留在mysql.innodb_ddl_log表中。在这种情况下,DDL日志会在恢复后重播并删除。

在系统恢复情况下,当服务器重新启动时,DDL操作可能会被提交或回滚。如果在DDL操作的提交阶段执行的数据字典事务存在于重做日志(redolog)二进制日志(binlog)中,则该操作被视为成功并向前滚动。否则,当InnoDB回放数据字典重做日志时,会回滚不完整的数据字典事务,并回滚DDL操作。

2.5 查看DDL日志

要查看在涉及innodb存储引擎的原子DDL操作期间写入mysql.innodb_ddl_log数据字典表的DDL日志,请启用innodb_print_ddl_logs,让mysql将DDL日志写入stderr。根据主机操作系统和MySQL配置的不同,stderr可能是错误日志终端控制台窗口。参见第7.4.2.2节“默认错误日志目标配置”。

InnoDB将DDL日志写入mysql.innodb_ddl_log表,以支持DDL操作的重做和回滚。mysql.innodb_ddl_log表是一个隐藏的数据字典表,位于mysql.ibd数据字典表空间中。与其他隐藏数据字典表一样,在mysql的非调试版本中,不能直接访问mysql.innodb_ddl_log表。(参见第16.1节“数据字典模式”。)mysql.innodb_ddl_log表的结构对应于此定义:

CREATE TABLE mysql.innodb_ddl_log (
  id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  thread_id BIGINT UNSIGNED NOT NULL,
  type INT UNSIGNED NOT NULL,
  space_id INT UNSIGNED,
  page_no INT UNSIGNED,
  index_id BIGINT UNSIGNED,
  table_id BIGINT UNSIGNED,
  old_file_path VARCHAR(512) COLLATE utf8mb4_bin,
  new_file_path VARCHAR(512) COLLATE utf8mb4_bin,
  KEY(thread_id)
);

各字段解析

id:DDL日志记录的唯一标识符。

thread_id:为每个DDL日志记录分配一个thread_id,用于重播和删除属于特定DDL操作的DDL日志。涉及多个数据文件操作的DDL操作会生成多个DDL日志记录。

type:DDL操作类型。类型包括FREE(删除索引树)、DELETE(删除文件)、RENAME(重命名文件)或drop(从mysql.innodb_dynamic_metadata数据字典表中删除元数据)。

space_id:表空间id。

page_no:包含分配信息的页面;例如索引树根页面。

index_id:索引id。

table_id:表id。

old_file_path:旧的表空间文件路径。用于创建或删除表空间文件的DDL操作;也用于重命名表空间的DDL操作。

new_file_path:新的表空间文件路径。由重命名表空间文件的DDL操作使用。


 此示例演示如何启用innodb_print_ddl_logs来查看为CREATE TABLE操作写入strderr的ddl日志。

mysql> SET GLOBAL innodb_print_ddl_logs=1;
mysql> CREATE TABLE t1 (c1 INT) ENGINE = InnoDB;
[Note] [000000] InnoDB: DDL log insert : [DDL record: DELETE SPACE, id=18, thread_id=7,
space_id=5, old_file_path=./test/t1.ibd]
[Note] [000000] InnoDB: DDL log delete : by id 18
[Note] [000000] InnoDB: DDL log insert : [DDL record: REMOVE CACHE, id=19, thread_id=7,
table_id=1058, new_file_path=test/t1]
[Note] [000000] InnoDB: DDL log delete : by id 19
[Note] [000000] InnoDB: DDL log insert : [DDL record: FREE, id=20, thread_id=7,
space_id=5, index_id=132, page_no=4]
[Note] [000000] InnoDB: DDL log delete : by id 20
[Note] [000000] InnoDB: DDL log post ddl : begin for thread id : 7
[Note] [000000] InnoDB: DDL log post ddl : end for thread id : 7

 可以理解为strderr为操作mysql.innodb_ddl_log表的输出,而mysql.innodb_ddl_log表为DDL的逻辑日志。回看上文这段话

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1684680.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

实用的TypeScript开发工具

1、根据接口数据自动定义类型变量:https://wulunyi.github.io/typeof-sjsonc-web/build/index.html ……(持续更新中)

Vue 离线地图实现

效果图: 一、获取市的地图数据 DataV.geoAtlas 获取市地图数据 点击地图缩放至想要的市区域,通过右侧的链接打开网址,复制json数据。 二、获取镇地图数据 选择你想要的镇数据,点击下载 选择级别(清晰度&#xff09…

关闭以及启动ubuntu图形界面

关闭以及启动ubuntu图形界面 文章目录 关闭以及启动ubuntu图形界面1. 关闭图形界面2. 打开图形界面 如果你误杀了Xorg进程,需要重新启动图形界面,可以按照以下步骤操作: 1. 关闭图形界面 查看当前启动的图形界面: 使用下面命令…

【linux系统学习教程 Day03】网络安全之Linux系统学习教程,用户和用户组管理,创建用户,删除用户,创建组,删除组....

1.7 用户和用户组管理 1.7.1 用户管理 1-1 创建用户 #创建用户 useradd #创建一个用户 例子1:useradd test1 #创建用户 useradd #创建一个用户 例子1:useradd dilnur 1-2 设置密码 passwd 例子1:passwd dilnur #用root用户给…

9.1 Go语言入门(环境篇)

Go语言入门(环境篇) 目录一、什么是Go语言二、下载安装配置Go语言开发环境1. 下载2. 安装3. 配置环境变量4. 安装环境验证 三、 开发工具1. 下载2. 安装3. 激活4. 配置SDK 四、 创建go工程文件并运行1. 创建go工程2. 示例代码3. 运行代码 目录 一、什么…

操作系统 c语言简单模仿进程创建和时间片轮转调度算法中的进程调度

1.实验目的 加深对进程概念的理解,明确进程和程序的区别; 深入了解系统如何组织进程、创建进程; 进一步认识如何实现处理器调度。 2.实验预备知识 进程的概念; 进程的组织方式; 进程的创建…

CCF20220601——归一化处理

CCF20220601——归一化处理 代码如下&#xff1a; #include<bits/stdc.h> using namespace std; int main() {int n,a[1000],sum0;scanf("%d",&n);for(int i1;i<n;i){scanf("%d",&a[i]);suma[i];}double aver1.0,b0.0,d1.0;aversum/(n*1…

深度学习之基于Django+Tensorflow卷积神经网络实时口罩检测系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景 随着全球疫情的持续&#xff0c;佩戴口罩成为了公众日常生活中不可或缺的一部分。特别是在人员密集的…

佛山远程抄表电表是什么?

1.佛山远程抄表电表&#xff1a;简述 佛山远程抄表电表&#xff0c;是一种利用通信网技术完成智能电表系统软件&#xff0c;它改变了传统的人工抄水表方式&#xff0c;提升了电力管理的效率和精确性。这类电表不但可以实时检测电力应用情况&#xff0c;还可以实现远程操作、全…

第二证券今日投资参考:5月国产游戏版号发放 猪价加速上涨

昨日&#xff0c;两市股指盘中震荡上扬&#xff0c;沪指盘中续创年内新高&#xff0c;创业板指一度涨超1%。到收盘&#xff0c;沪指涨0.54%报3171.15点&#xff0c;深证成指涨0.43%报9750.82点&#xff0c;创业板指涨0.59%报1875.93点&#xff0c;上证50指数涨0.34%&#xff1b…

Vue学习穿梭框Transfer组件

Vue学习Transfer组件 一、前言1、案例一2、案例二 一、前言 在 Vue 3 中使用 el-transfer 组件可以帮助你实现数据的穿梭功能&#xff0c;让用户可以将数据从一个列表转移到另一个列表。下面是一个简单示例&#xff0c;演示如何在 Vue 3 中使用 el-transfer 组件&#xff1a; …

C语言 数组——向函数传递数组

目录 把数组传给函数&#xff08;Passing Arrays to Functions&#xff09; 向函数传递一维数组 向函数传递二维数组 数组在学生成绩管理中的应用 例&#xff1a;计算每个学生的平均分 把数组传给函数&#xff08;Passing Arrays to Functions&#xff09; 向函数传递一维…

Harbor 使用中出现的问题

安装 使用宝塔安装 安装成功的标志&#xff0c;见下图。初始的默认用户是admin&#xff0c;密码是Harbor12345&#xff0c;登录成功&#xff1a; 错误现象 # docker login 192.168.1.50:8005 Username: admin Password: Error response from daemon: Get "https://1…

民国漫画杂志《时代漫画》第18期.PDF

时代漫画18.PDF: https://url03.ctfile.com/f/1779803-1248612707-27e56b?p9586 (访问密码: 9586) 《时代漫画》的杂志在1934年诞生了&#xff0c;截止1937年6月战争来临被迫停刊共发行了39期。 ps:资源来源网络&#xff01;

./scripts/Makefile.clean 文件分析

文章目录 目标 $(subdir-ymn)目标__clean $(clean-dirs):     make -f ./scripts/Makefile.clean obj$(patsubst _clean_%,%,$) $(clean-dirs)$(patsubst _clean_%,%,$)_clean_api _clean_cmd _clean_common _clean_disk _clean_drivers _clean_drivers/ddr/altera _clean_d…

【spring】@CrossOrigin注解学习

CrossOrigin介绍 CrossOrigin 是 Spring Framework 中的一个注解&#xff0c;用于处理跨域资源共享&#xff08;CORS&#xff09;问题。CORS 是一种机制&#xff0c;它使用额外的 HTTP 头来告诉浏览器&#xff0c;让运行在一个 origin (domain) 上的Web应用被准许访问来自不同…

linux 安装redis 并设置开机启动

个人实测 流程 1、第一步 先下载redis ** redis地址 https://download.redis.io/releases/选择你想要的版本 我下载的是 如下图 2、第二步:把下载的包放到linux里面 我用的是 XSHELL 和XFTP 放到/usr/local/java路径下 你可以随便放 3、第三步: ** 执行 以下命令 进行解压 t…

10最佳iPhone数据恢复软件评论

您还在寻找最好的iPhone数据恢复软件吗&#xff1f; 似乎我们在iPhone上放置了越来越多与日常生活和工作有关的重要事情。照片可以保持珍贵的时刻&#xff0c;联系人可以保持联系&#xff0c;录音&#xff0c;备忘录和日历可以作为提醒&#xff0c;视频和歌曲可以娱乐&#xf…

“现代汽车中国前瞻软件赛杯” 牛客周赛 Round 43

A. 小红平分糖果&#xff08;签到&#xff09; // Problem: 小红平分糖果 // Contest: NowCoder // URL: https://ac.nowcoder.com/acm/contest/82394/A // Memory Limit: 524288 MB // Time Limit: 2000 ms // // Powered by CP Editor (https://cpeditor.org)#include<b…

史上最快AI大模型炸场!人工智能将如何影响你的未来?

一觉醒来&#xff0c;每秒能输出500个tokens的大模型Groq刷屏全网。 堪称是“世界上速度最快的LLM”&#xff01; 相比之下&#xff0c;ChatGPT-3.5每秒生成速度仅为40个tokens(token&#xff0c;中文名称为令牌&#xff0c;是一种特殊的计算机术语&#xff0c;常用于网络通讯…