MySQL · 捉虫动态·DROP DATABASE外键约束的GTID BUG

本文涉及的产品
云数据库 RDS SQL Server,基础系列 2核4GB
云原生数据库 PolarDB 分布式版,标准版 2核8GB
RDS PostgreSQL Serverless,0.5-4RCU 50GB 3个月
推荐场景:
对影评进行热评分析
简介: 背景 MySQL的DDL没有被设计成事务操作,因此DDL操作是无法回滚的(像PgSQL把DDL也设计成事务操作,DDL就可以在执行成功后被回滚操作取消)。这就会导致如果某个DDL语句内部被拆分为多个原子的DDL调用,那么这个DDL语句就不具备中途执行失败后回滚整个DDL语句的能力,也就是说,即使语

背景

MySQL的DDL没有被设计成事务操作,因此DDL操作是无法回滚的(像PgSQL把DDL也设计成事务操作,DDL就可以在执行成功后被回滚操作取消)。这就会导致如果某个DDL语句内部被拆分为多个原子的DDL调用,那么这个DDL语句就不具备中途执行失败后回滚整个DDL语句的能力,也就是说,即使语句逻辑内的某个原子DDL调用失败了,也无法回滚已经完成的那些原子DDL调用。


问题描述

DROP DATABASE 就是一个例子,对于MySQL而言,DROP DATABASE 并非是一个原子DDL操作,因为它是一个个删除DB下的每张表,而 DROP TABLE 操作本身是会做预检查的,无法删除就会取消删表操作返回失败,所以 DROP TABLE 才能认为是原子的DDL调用。 这就会引起一个问题,如果一个DB中的某张表DROP失败了,实际上 DROP DATABASE 作为一个整体是执行失败的,但是DB中已经有一些表被删除了,因此Binlog中会记录成多个 DROP TABLE 操作,而不是一个 DROP DATABASE 语句。 如果被删除的表的表名都不长,还是会记录成一个删除多张表的 DROP TABLE 语句(DROP TABLE tbl1, tbl2, ...),但是如果表名总长度太长,MySQL会拆分为多个 DROP TABLE 语句来记录。 没有GTID的时候这似乎也不是什么大问题,但是引入GTID之后就有一个问题:每个语句只分配一个GTID。如果一个 DROP DATABASE 语句被拆分为多个 DROP TABLE 语句,Binlog中就会出现多个 DROP TABLE 事件共用一个GTID的情况!

举个例子:

 

这里因为 db2.t3 表引用了 db1.t1 的字段作为外键约束,所以当 db1 做 DROP DATABASE 删除到 t1 表时就报错了,但此时很多表已经被删除了。我们看Binlog中记录的内容:

 

3个 DROP TABLE 语句都是同一个GTID:340d95b8-a699-11e4-868d-a0d3c1f20ae4:61

这就导致备库复制报错:

 


解决方案

怎么解决这个问题呢?

1. 让MySQL支持DDL事务

2. 对DROP DATABASE操作进行预检查


第一种方案对MySQL改动太大了,完全不现实。因此我们采用了第二种方案,也间接实现了 DROP DATABASE 这个操作的原子性。 DROP DATABASE 之所以出现上面的状况,就是因为没有先检查表是否可以删除,而是走一步看一步,一个个删的时候才看能不能删除。我们对MySQL做了修正,对于DB中的每张表,在 DROP DATABASE 执行之前,都先预检查所有可能导致删除表失败的条件,如果一旦发现某张表会无法删除,就放弃整个 DROP DATABASE 操作,提示用户删除错误,让用户先自行解决问题后,再重新执行 DROP DATABASE。

例如上面例子中的情况,本来 DROP DATABASE 执行到有外键约束的表时会报错:

 

但此时其他表已经删除了,而我们修正以后,同样的操作会报一个Error和一个Warning,并且没有真的删任何表:

 

这里提示了用户有表存在问题无法删除,让用户先处理掉之后,再来执行 DROP DATABASE。此时库下面所有的表都还在,一定要预检查通过才会真的删除。


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
4月前
Mybatis+mysql动态分页查询数据案例——测试类HouseDaoMybatisImplTest)
Mybatis+mysql动态分页查询数据案例——测试类HouseDaoMybatisImplTest)
|
4月前
Mybatis+mysql动态分页查询数据案例——房屋信息的实现类(HouseDaoMybatisImpl)
Mybatis+mysql动态分页查询数据案例——房屋信息的实现类(HouseDaoMybatisImpl)
|
3月前
|
关系型数据库 MySQL
MYSQL-多表操作-外键约束
MYSQL-多表操作-外键约束
|
1月前
|
存储 SQL 关系型数据库
在 MySQL 中使用 Drop Database
【8月更文挑战第11天】
91 0
在 MySQL 中使用 Drop Database
|
4月前
Mybatis+mysql动态分页查询数据案例——工具类(MybatisUtil.java)
Mybatis+mysql动态分页查询数据案例——工具类(MybatisUtil.java)
|
1月前
|
SQL 关系型数据库 MySQL
(十八)MySQL排查篇:该如何定位并解决线上突发的Bug与疑难杂症?
前面《MySQL优化篇》、《SQL优化篇》两章中,聊到了关于数据库性能优化的话题,而本文则再来聊一聊关于MySQL线上排查方面的话题。线上排查、性能优化等内容是面试过程中的“常客”,而对于线上遇到的“疑难杂症”,需要通过理性的思维去分析问题、排查问题、定位问题,最后再着手解决问题,同时,如果解决掉所遇到的问题或瓶颈后,也可以在能力范围之内尝试最优解以及适当考虑拓展性。
|
2月前
|
存储 数据库
DROP DATABASE 语句
【7月更文挑战第20天】DROP DATABASE 语句。
42 3
|
2月前
|
SQL 关系型数据库 MySQL
实时计算 Flink版产品使用问题之如何进行MySQL到MySQL的动态同步
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
3月前
|
关系型数据库 MySQL Serverless
实时计算 Flink版产品使用问题之使用cdas语法同步mysql数据到sr serverless是否支持动态加表
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
3月前
|
SQL 存储 关系型数据库
17. Mysql 动态SQL
17. Mysql 动态SQL
56 1

相关产品

  • 云数据库 RDS MySQL 版