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)

大家都在看

  • MySQL函数1(单行函数)

    单行函数 函数的理解 分类 数值函数 基本函数 PI()无参数 CETL \ CETLING()天花板函数(取比自己大的相邻的数) FLOOR()地板函数(取比自己小的相邻的数) …

    数据库 2023年5月24日
    0102
  • 记录一次数据库CPU被打满的排查过程

    1 前言 近期随着数据量的增长,数据库CPU使用率100%报警频繁起来。第一个想到的就是慢Sql,我们对未合理运用索引的表加入索引后,问题依然没有得到解决,深入排查时,发现在 or…

    数据库 2023年5月24日
    0115
  • pg数据库匹配正则

    select ‘41142619960609331x’ ~ ‘^[1-9]\d{5}\d{4}((0[1-9])|(10|11|12))(([0…

    数据库 2023年6月16日
    095
  • 【黄啊码】MySQL复制以及调优

    一. 简介 MySQL自带复制方案,带来好处有: 数据备份。负载均衡。分布式数据。 概念介绍: 主机(master):被复制的数据库。从机(slave):复制主机数据的数据库。 复…

    数据库 2023年6月16日
    0117
  • Linux–>进程管理

    基本介绍 在Linux中, 每个执行程序都称为一个进程。每一个进程都会分配一个ID号(pid,进程号) 每个进程都可能以俩种方式存在的。分别是 前台与 后台,所谓前台进程就是用户目…

    数据库 2023年6月14日
    0107
  • MySQL 视图简介

    对数据库中数据的查询有时是非常复杂的,如表连接、子查询等。这种查询很难写,而且容易出错。此外,当您专门操作表时,有时只需要操作部分字段。 [En] The query about …

    数据库 2023年5月24日
    0112
  • JWT+SpringSecurity登录和权限管理

    一、什么是JWT 说起JWT,我们应该来谈一谈基于token的认证和传统的session认证的区别。说起JWT,我们应该来谈一谈基于token的认证和传统的session认证的区别…

    数据库 2023年6月6日
    0105
  • django-nginx与uwsgi项目部署

    uwsgi是提供动态服务的 nginx反向代理 在项目中创建一个settings.py的副本。我这里重命名为copy_settings.py,将配置文件中的DEBUG=False …

    数据库 2023年6月6日
    0105
  • 分享封装好的异步Mysql动态的库(DyNetMysql.dll) + 项目源码

    在做C++项目时,经常会用到Mysql数据库,Mysql接口提供给我们的数据是相当原始的,如:字段名、字段类型,字段长度等等,一般情况我们都想一种更方便获得数据 如: XXXStr…

    数据库 2023年6月14日
    085
  • 查看PostgreSQL监听端口

    如何查看PostgreSQL的监听端口呢?下面总结一下查看PostgreSQL监听端口的方法。 方法1:netstat命令查看 或者sudo netstat -plunt |gre…

    数据库 2023年6月11日
    087
  • bbs项目前期准备和表设计

    一、前期准备 1.新建一个django项目 2….

    数据库 2023年6月14日
    083
  • 简单聊聊mysql的脏读、不可重复读、幻读

    最近,在一次 mysql 死锁的生产事故中,我发现,关于 mysql 的锁、事务等等,我所知道的东西太碎了,所以,我试着用几个例子将它们串起来。具体做法就是通过不断地问问题、回答问…

    数据库 2023年5月24日
    0111
  • .NET在单台Windows2008下百万TCP连接测试

    测试客户端: 客户端程序建立TCP连接,发送一条几个字节的数据。 虚拟机8 台,PC 机8 台,服务器1 台。 设置MaxUserPort=60000 ,有一台机没有设置约在1.5…

    数据库 2023年6月14日
    0129
  • PostgreSQL 和 MySQL 在用途、好处、特性和特点上的异同

    PostgreSQL 和 MySQL 在用途、好处、特性和特点上的异同。 PostgreSQL 和 MySQL 是将数据组织成表的关系数据库。这些表可以根据每个表共有的数据链接或关…

    数据库 2023年5月24日
    0110
  • 10 Math.round(11.5) 等于多少,Math.round(-11.5)等于多少

    Math.round():将括号内的数+0.5,然后向下取整 11.5 + 0.5 = 12,向下取整即12 -11.5 + 0.5 = -11,向下取整即-11 Original…

    数据库 2023年6月6日
    0118
  • Jmeter性能测试场景的创建和运行

    目录 性能测试场景的分析 项目背景 Jmeter指标 性能测试场景的设计以及准备 * 性能测试的总结 性能测试场景的分析 项目背景 ​ 实际工作中,我们拿到一个项目一般来说都会是项…

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