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

本文涉及的产品
PolarSearch,搜索节点 4核8GB
RDS AI 助手,专业版
PolarDB Agent Flow,2核4GB
简介: 背景 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。此时库下面所有的表都还在,一定要预检查通过才会真的删除。


相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
目录
相关文章
|
10月前
|
存储 安全 关系型数据库
MySQL数据库约束条件概述及其重要性讨论。
正确地实现并管理好各类紧缩条件将直接影响到企业信息管理水平与服务质量,在当今大数据背景下更显得格外重要;任何设计师都需要深刻理解其原理与运作机晰承担起责任使得所托管资料安全稳固同时又具备良好伸缩灵活度迎合日益复杂商务需求变动.
288 11
|
SQL 关系型数据库 MySQL
【揭秘】MySQL binlog日志与GTID:如何让数据库备份恢复变得轻松简单?
【8月更文挑战第22天】MySQL的binlog日志记录数据变更,用于恢复、复制和点恢复;GTID为每笔事务分配唯一ID,简化复制和恢复流程。开启binlog和GTID后,可通过`mysqldump`进行逻辑备份,包含binlog位置信息,或用`xtrabackup`做物理备份。恢复时,使用`mysql`命令执行备份文件,或通过`innobackupex`恢复物理备份。GTID模式下的主从复制配置更简便。
2011 2
|
NoSQL 关系型数据库 MySQL
2024Mysql And Redis基础与进阶操作系列(4-2)作者——LJS[含MySQL非空、唯一性、PRIMARY KEY、自增列/自增约束举例说明等详解步骤及常见报错问题对应的解决方法]
24MySQL非空、唯一性、PRIMARY KEY、自增列/自增约束举例说明等详解步骤及常见报错问题对应的解决方法(4-2) 学不会你来砍我!!!
|
存储 SQL 关系型数据库
【MySQL基础篇】MySQL约束语法
文章介绍了MySQL中表的约束概念,包括非空、唯一、主键、默认和外键约束,以及如何在创建和修改表时指定这些约束。外键约束用于保持数据的一致性和完整性,文章通过示例展示了添加、删除外键的语法,并讨论了不同的删除/更新行为,如CASCADE和SETNULL。
【MySQL基础篇】MySQL约束语法
|
SQL 关系型数据库 MySQL
MySQL中外键的使用及外键约束策略
这篇文章讨论了MySQL中使用外键的重要性,包括外键的概念、不使用外键可能导致的问题、如何设置外键约束以及不同的外键约束策略(如CASCADE和SET NULL),并通过示例演示了这些概念。
MySQL中外键的使用及外键约束策略
|
关系型数据库 MySQL 数据处理
MySQL函数与约束
MySQL 提供了丰富的函数和强大的约束机制,用于数据处理和完整性维护。通过掌握这些工具,可以有效地管理和分析数据库中的数据,确保数据的一致性和准确性。无论是在日常数据查询中使用内置函数,还是在数据库设计中应用各种约束,都是确保数据库系统稳定、高效运行的关键。希望本文对您理解和应用 MySQL 函数与约束有所帮助。
241 1
|
存储 关系型数据库 MySQL
MySQL(条件约束)
为了校验数据,让数据的正确性能够得到保证,约束,能够引进更多的检查操作,但是也会增加系统的成本开销
|
Ubuntu 关系型数据库 MySQL
ubuntu使用aliyun源+mysql删除有外键约束的数据+查看特定目录的大小
ubuntu使用aliyun源+mysql删除有外键约束的数据+查看特定目录的大小
277 4
|
关系型数据库 MySQL 测试技术
MySQL外键使用的考量与建议
综上所述,虽然MySQL的外键提供了一种强大的工具来维护数据之间的一致性和完整性,但在决定是否使用外键时,需要权衡其带来的好处和潜在的性能影响。通过仔细的规划和测试,可以最大化地利用外键的优势,同时避免一些常见的陷阱。
269 3
|
关系型数据库 MySQL 测试技术
MySQL外键使用的考量与建议
综上所述,虽然MySQL的外键提供了一种强大的工具来维护数据之间的一致性和完整性,但在决定是否使用外键时,需要权衡其带来的好处和潜在的性能影响。通过仔细的规划和测试,可以最大化地利用外键的优势,同时避免一些常见的陷阱。
549 1

相关产品

  • 云数据库 RDS MySQL 版
  • 推荐镜像

    更多