MySQL 中如何定位 DDL 被阻塞的问题

经常碰到开发、测试童鞋会问,线下开发、测试环境,执行了一个DDL,发现很久都没有执行完,是不是被阻塞了?要怎么解决?

包括在群里,也经常会碰到类似问题:DDL 被阻塞了,如何找到阻塞它的 SQL ?

实际上,如何解决 DDL 被阻塞的问题,是 MySQL 中一个共性且高频的问题。

在这里,让我们为这个问题提供一个明确的、现成的解决方案:

[En]

Here, let’s give a clear and ready-to-use solution to this problem:

怎么判断一个 DDL是不是被阻塞了?

首先,看一个简单的Demo

判断一个 DDL 是不是被阻塞了,很简单,就是执行 show processlist ,查看 DDL 操作对应的状态。

如果显示的是 Waiting for table metadata lock ,则意味着这个 DDL 被阻塞了。

DDL 一旦被阻塞了,后续针对该表的所有操作都会被阻塞,都会显示 Waiting for table metadata lock 。这也是 DDL 让人闻之色变的原因。

碰到了类似场景,要么 Kill DDL 操作,要么 Kill 阻塞 DDL 的会话。

Kill DDL 操作是一个治标不治本的方法,毕竟 DDL 操作总要执行。

除此之外,对于 DDL 操作,需要获取元数据库锁的阶段有两个:DDL 开始之初和 DDL 结束之前。如果是后者,就意味着之前的操作都要回滚,成本相对较高。

所以,碰到类似场景,我们一般都会 Kill 阻塞 DDL 的会话。

那么,怎么知道是哪些会话阻塞了 DDL 呢?

我们来看看具体的定位方法。

[En]

Let’s take a look at the specific positioning methods.

定位方法

sys.schema_table_lock_waits 是MySQL 5.7引入的,用来定位 DDL 被阻塞的问题。

针对上面这个Demo。

我们看看sys.schema_table_lock_waits的输出。

只有一个 alter 操作,却产生了两条记录,而且两条记录的 Kill 对象还不一样,其中一条 Kill 的对象还是 alter 操作本身。

如果对表结构不熟悉或不仔细看记录内容的话,难免会 Kill 错对象。

不仅如此,在 DDL 操作被阻塞后,如果后续有 N 个查询被 DDL 操作堵塞,还会产生 N*2 条记录。

在定位问题时,这 N*2 条记录完全是个噪音。

此时,我们需要对上述记录进行过滤。

[En]

At this time, we need to filter the above records.

过滤的关键是 blocking_lock_type 不等于 SHARED_UPGRADABLE。

SHARED_UPGRADABLE 是一个可升级的共享元数据锁,加锁期间,允许并发查询和更新,常用在 DDL 操作的第一阶段。

所以,阻塞DDL的不会是SHARED_UPGRADABLE。

故而,针对上面这个 case,我们可以通过下面这个查询来精确地定位出需要 Kill 的会话。

sys.schema_table_lock_waits 是 MySQL 5.7 才引入的。

但在实际生产环境,MySQL 5.6还是占有相当多的份额。

如何解决MySQL 5.6的这个痛点呢 ?

细究下来,导致 DDL 被阻塞的操作,无非两类:

其中,第一类比较好定位,通过 show processlist 就能发现。

所以,网上有 Kill 空闲连接的说法,其实也不无道理,但这样做就太简单粗暴了,难免会误杀。

其实,既然是事务,在 information_schema.innodb_trx中肯定会有记录,如 session1 中的事务,在表中的记录如下,

其中 trx_mysql_thread_id 是线程 id ,结合 information_schema.processlist ,可进一步缩小范围。

所以,我们可以通过下面这个 SQL ,定位出执行时间早于 DDL 的事务。

可喜的是,当前正在执行的查询也会显示在information_schema.innodb_trx中。

所以,上面这个 SQL 同样也适用于慢查询未结束的场景。

sys.schema_table_lock_waits 视图依赖了一张 MDL 相关的表-performance_schema.metadata_locks。

该表是 MySQL 5.7 引入的,会显示 MDL 的相关信息,包括作用对象、锁的类型及锁的状态等。

但在 MySQL 5.7 中,该表默认为空,因为与之相关的 instrument 默认没有开启。MySQL 8.0 才默认开启。

开启方式很简单,直接修改 performance_schema.setup_instruments 表即可。

具体SQL如下。

但是,此方法暂时生效,重启实例时会恢复到默认值。

[En]

However, this method takes effect temporarily, and when the instance is restarted, it will return to the default value.

建议同步修改配置文件。

  1. 执行 show processlist ,如果 DDL 的状态是 Waiting for table metadata lock ,则意味着这个 DDL 被阻塞了。

  2. 定位导致 DDL 被阻塞的会话,常用的方法有两种:

2.1 sys.schema_table_lock_waits

这种方法适用于 MySQL 5.7 和 8.0。

注意,MySQL 5.7 中,MDL 相关的 instrument 默认没有打开。

2.2 Kill DDL 之前的会话

如果 MySQL 5.7 中 MDL 相关的 instrument 没有打开或在 MySQL 5.6 中,可使用该方法。

Original: https://www.cnblogs.com/ivictor/p/15787546.html
Author: iVictor
Title: MySQL 中如何定位 DDL 被阻塞的问题

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/507886/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 自然对数

    https://zhuanlan.zhihu.com/p/71928040自然对数 https://www.youtube.com/watch?v=mZE0RmCbDe8 本文来自…

    数据库 2023年6月11日
    0121
  • Spring Security实现统一登录与权限控制

    1 项目介绍 最开始是一个单体应用,所有功能模块都写在一个项目里,后来觉得项目越来越大,于是决定把一些功能拆分出去,形成一个一个独立的微服务,于是就有个问题了,登录、退出、权限控制…

    数据库 2023年6月14日
    0105
  • MySQL45讲之InnoDB刷脏策略

    本文介绍 InnoDB 的刷脏控制策略,它是如何控制刷脏速率的,以及一些相关参数。 了解 MySQL 的刷脏策略有什么意义? 当一条正确的 SQL 执行时偶尔延迟较高,无法复现场景…

    数据库 2023年5月24日
    094
  • 启用Hyper-v后,重启后界面提示 无法完成功能配置,正在撤销更改

    安装docker后,提示需要启用hyper-v,在控制面板中勾选Hyper-v,然后重启,更新快完成就提示无法完成功能配置,正在撤销更改 解决方法 方法1 控制面板一个一个选 方法…

    数据库 2023年6月14日
    0129
  • 记录不存在则插入,存在则更新 → MySQL 的实现方式有哪些?

    开心一刻 今天,爸爸、我和女儿一起吃了晚饭,我们每人都吃了一只鸡腿。 [En] Today, my father, me and my daughter had dinner to…

    数据库 2023年5月24日
    0107
  • @JsonFormat和@DateTimeFormat的作用

    @DatetimeFormat是将String转换成Date,一般前台给后台传值时用 import org.springframework.format.annotation.Da…

    数据库 2023年6月14日
    088
  • java实现有道翻译爬虫

    我的博文地址 https://www.cnblogs.com/lingdurebing/p/11618902.html 使用的库 1.commons-codec 主要是为了加密,可…

    数据库 2023年6月11日
    0107
  • MySQL之存储引擎、基本数据类型及约束条件

    一、存储引擎 数据库存储引擎是数据库底层软件组织,数据库管理系统(DBMS)使用数据引擎进行创建、查询、更新和删除数据。不同的存储引擎提供不同的存储机制、索引技巧、锁定水平等功能,…

    数据库 2023年5月24日
    077
  • 一,Flink快速上手

    1.依赖配置 1.1 pom文件 8 8 1.13.0 1.8 2.12 1.7.30 org.apache.flink flink-java ${flink.version} o…

    数据库 2023年6月6日
    0101
  • 系统设计的11个考虑

    有了《系统架构的11条原则》,真正到设计阶段还有另外11个考虑。 系统正确性 考虑一:负负得正 假如我们看到某个代码,明显有逻辑错误,想随手改改。你就要考虑一件事情:这段明显有问题…

    数据库 2023年6月6日
    088
  • day44-反射03

    Java反射03 3.通过反射获取类的结构信息 3.1java.lang.Class类 getName:获取全类名 getSimpleName:获取简单类名 getFields:获…

    数据库 2023年6月11日
    085
  • 2022-08-17 DQL—-子查询,日期格式

    子查询、日期格式 DQL查询语言 子查询 按照结果集的行列数不同,子查询可以分为以下几类: 标量子查询:结果集只有一行一列(单行子查询) 列子查询:结果集有一列多行 行子查询:结果…

    数据库 2023年6月14日
    097
  • 慢SQL,压垮团队的最后一根稻草!

    一、什么是慢 SQL 什么是慢SQL? 顾名思义,运行时间较长的 SQL 语句即为慢 SQL! 那问题来了,多久才算慢呢? 这个慢其实是一个相对值,不同的业务场景下,标准要求是不一…

    数据库 2023年6月14日
    0105
  • MySQL学习笔记

    MySQL学习笔记 解决MYSQL中文乱码问题 一、乱码的原因: 1、 client客户端的编码不是utf8 2、server端的编码不是utf8 3、database数据库的编码…

    数据库 2023年6月14日
    0101
  • 23种设计模式之观察者模式

    文章目录 概述 观察者模式的优缺点 观察者模式应用场景 观察者模式的结构和实现 * 模式结构 模式实现 总结 ; 概述 观察者模式很好理解,类似于邮件订阅和RSS订阅,当我们浏览一…

    数据库 2023年6月6日
    0112
  • PHP array_count_values()

    array_count_values array_count_values() 函数用于统计数组中所有值出现的次数。 本函数返回一个数组,其元素的键名是原数组的值,键值是该值在原数…

    数据库 2023年6月14日
    079
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球