热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

ddl不显示触发器navicat_新特性解读|MySQL8.0之原子DDL

作者:杨奇龙网名“北在南方”,8年DBA老兵,目前任职于杭州有赞科技DBA,主要负责数据库架构设计和运维平台开发工作
作者:杨奇龙
网名“北在南方”,8 年 DBA 老兵,目前任职于杭州有赞科技 DBA,主要负责数据库架构设计和运维平台开发工作,擅长数据库性能调优、故障诊断。
本文来源:转载自公众号-yangyidba
*爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。

本文关键字:原子 DDL 、数据字典

原子 DDL

听到原子这个关键字大家是不是联想到事务的 ACID 的原子性?两者相似,事务/语句执行要么全部成功,要么全部失败。MySQL 8.0 之前的版本 DDL 是非原子性的,对于多条 sql 构成的ddl语句比如rename table t1 to t1_bak,t2 to t2_bak;

执行过程中如果遇到系统异常 crash,有可能出现表 t1 被 rename,但是 t2 没有被 rename 的情况。出现该情况的原因就是 MySQL 不支持原子的 DDL。

MySQL 8.0 之前的数据字典结构图:

4f611bcbabca1714013a7294e1509cd3.png

从图中我们可以看出,元数据信息在存储于.FRM.TRG.OPT文件系统,MyISAM 引擎的系统表里,以及 Innodb 存储引擎的系统表。分裂成多处这样的架构导致在系统异常的情况下很容易造成数据的不一致。

MySQL 8.0 的数据字典结构图:

4c90e1fddafe6632ea542baa0280134d.png

从图中我们明显可以看出 Data Dictionary 全部存在于由 InnoDB 表构成的系统表中

Data Dictionary Table。当遇到 crash recovery 的时候,系统可以安全的进行事务回滚,保障 DDL 语句的原子性。说了这么多,我们动手实践一下 。

案例实践

对比 5.7 vs 8.0 的测试图,MySQL 5.7.22 DDL 操作删除两个表,其中一个 t2 不存在。

2d3b4bad27a7a17c85ded61be2dca2e9.png

MySQL 8.0.20 的原子性操作,

619c44f213fc39163fb29d0760b99616.png

MySQL 8.0 支持原子性,DDL 失败之后 t1 还在,但是5.7 版本中 t1 就被删除了。

原子 DDL 操作步骤

InnoDB 存储引擎执行 DDL 时是分阶段进行的。比如 ALTER TABLE,可能会在执行提交阶段之前多次执行准备阶段和执行阶段的操作。

  • 准备:创建所需的对象,并且将 DDL 日志写入 mysql.innodb_ddl_log 表中。DDL 日志定义了如何前滚和回滚相应的 DDL 操作。
  • 执行:执行 DDL 操作。例如,为 CREATE TABLE 执行创建操作。
  • 提交:更数据字典并提交数据字典事务。
  • Post-DDL:重放并删除 mysql.innodb_ddl_log 表中的 DDL 日志。为了能够安全地执行回滚操作而不会导致不一致性,对于文件的操作,例如重命名数据文件或移动数据文件,放在这个最后的阶段执行。这个阶段还会为 DROP TABLE、TRUNCATE TABLE 以及其他重建表的 DDL 操作删除数据字典表 mysql.innodb_dynamic_metadata 中的动态元数据。

无论事务被提交还是回滚,在 Post-DDL 阶段都会重放并删除 mysql.innodb_ddl_log 表中的 DDL 日志。只有当服务器在执行 DDL 操作的过程中出现故障时,才会在 mysql.innodb_ddl_log 表中保留 DDL 日志。这种情况下,在服务器恢复之后执行 DDL 日志的重放和删除。

对于需要进行恢复的情况,服务器重启之后,可能执行 DDL 事务的提交,也可能执行事务的回滚。如果在提交阶段执行的数据字典事务已经记录在重做日志和二进制日志中,就会认为 DDL 操作已经成功,并且执行前滚操作。否则,当 InnoDB 重放数据字典重做日志的时候,将会回滚不完整的数据字典事务,并且回滚 DDL 事务。

查看 DDL 日志

为了支持 原子 DDL,InnoDB 在执行 DDL 语句时将日志写入隐藏的数据字典表mysql.innodb_ddl_log中,该表存储在 mysql.ibd 数据字典表空间。所谓隐藏数据字典表,就是在不能以正常的方式直接访问,得在调试 debug 模式下访问隐藏表。

CREATE TABLE mysql.innodb_ddl_log (id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,#每条 DDL 日志记录的唯一标识符。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 UTF8_BIN,new_file_path VARCHAR(512) COLLATE UTF8_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=1log_error_verbosity=3在 MySQL 的 系统日志里面查看 DDL log,比如我运行的 MySQL 8.0 是在 docker 中 ,使用docker logs mysql8.0

8236c594d9f1640469d1d2c11014df7d.png

日志表示执行 create table t2 的 ddl 日志过程。

MySQL 8.0 原子 DDL 使用范围

支持的 ddl 范围

  • 与表相关的原子 DDL 包括:
    数据库、表空间、表、索引的 CREATE、ALTER 以及 DROP 语句,以及 TRUNCATE TABLE 语句。
  • 与表无关的原子 DDL 包括:
    存储过程、触发器、视图以及用户定义函数 UDF 的 CREATE 和 DROP 语句,以及适用的 ALTER 语句。
    帐户管理语句:用户和角色的 CREATE、ALTER、DROP 语句,以及适用的 RENAME 语句,以及 GRANT 和 REVOKE 语句。

不支持的 ddl 范围

  • 非 InnoDB 存储引擎上的表相关 DDL 语句。
  • INSTALL PLUGIN 和 UNINSTALL PLUGIN 语句。
  • INSTALL COMPONENT 和 UNINSTALL COMPONENT 语句。
  • CREATE SERVER、ALTER SERVER 以及 DROP SERVER 语句。

小结

本文基本就是官方文档加上系统开发团队 blog 内容的二道贩子,理解不正确的,大家可以积极指正。其他的还是推荐看看官方文档。



推荐阅读
  • 初始化_SQL Server 2017 AlwaysOn AG 自动初始化
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了SQLServer2017AlwaysOnAG自动初始化相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • 本文介绍了三种方法来实现在Win7系统中显示桌面的快捷方式,包括使用任务栏快速启动栏、运行命令和自己创建快捷方式的方法。具体操作步骤详细说明,并提供了保存图标的路径,方便以后使用。 ... [详细]
  • mysql-cluster集群sql节点高可用keepalived的故障处理过程
    本文描述了mysql-cluster集群sql节点高可用keepalived的故障处理过程,包括故障发生时间、故障描述、故障分析等内容。根据keepalived的日志分析,发现bogus VRRP packet received on eth0 !!!等错误信息,进而导致vip地址失效,使得mysql-cluster的api无法访问。针对这个问题,本文提供了相应的解决方案。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • 使用eclipse创建一个Java项目的步骤
    本文介绍了使用eclipse创建一个Java项目的步骤,包括启动eclipse、选择New Project命令、在对话框中输入项目名称等。同时还介绍了Java Settings对话框中的一些选项,以及如何修改Java程序的输出目录。 ... [详细]
  • linuxmint20.3 安装anaconda、换源及创建新环境
    本文用来记录linuxmint20.3安装anaconda、换源及创建新环境的过程,同时记录一些相关命令目录anaconda安装相关命令创建新环境显示问题 ... [详细]
  • 使用R包提供的数据是学习数据科学工具的好方法,但是在某个时候,您希望停止学习,开始使用自己的数据。在本章中,您将学习如何将纯文本矩形文件读入r。在这里,我们只讨论数据导入的皮毛,但 ... [详细]
  • 一条数据的漫游 XEngine SIGMOD Paper Introduction
    大多数人追寻永恒的家园(归宿),少数人追寻永恒的航向。----瓦尔特.本雅明背景X-Engine是阿里数据库产品事业部自研的OLTP数据库存储引擎, ... [详细]
  • 安装mysqlclient失败解决办法
    本文介绍了在MAC系统中,使用django使用mysql数据库报错的解决办法。通过源码安装mysqlclient或将mysql_config添加到系统环境变量中,可以解决安装mysqlclient失败的问题。同时,还介绍了查看mysql安装路径和使配置文件生效的方法。 ... [详细]
  • 本文介绍了深入浅出Linux设备驱动编程的重要性,以及两种加载和删除Linux内核模块的方法。通过一个内核模块的例子,展示了模块的编译和加载过程,并讨论了模块对内核大小的控制。深入理解Linux设备驱动编程对于开发者来说非常重要。 ... [详细]
  • 在Oracle11g以前版本中的的DataGuard物理备用数据库,可以以只读的方式打开数据库,但此时MediaRecovery利用日志进行数据同步的过 ... [详细]
  • 出现_史上最大漏洞出现,你的安卓iPhone电脑都不安全了!
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了史上最大漏洞出现,你的安卓iPhone电脑都不安全了!相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 【Java编码规范】《阿里巴巴Java开发手册(正式版)》发布!
    2019独角兽企业重金招聘Python工程师标准2017年开春之际,诚意献上重磅大礼:阿里巴巴Java开发手册,首次公开阿里官方Ja ... [详细]
  • 数据库异常智能分析与诊断
    数据库,异常, ... [详细]
author-avatar
0o可人儿o0_962
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有