MySQL数据库 DDL 阻塞问题定位 【转载】

陈臣,甲骨文MySQL首席解决方案工程师,公众号《MySQL实战》作者,有大规模的MySQL,Redis,MongoDB,ES的管理和维护经验,擅长MySQL数据库的性能优化及日常操作的原理剖析。

经常碰到开发、测试童鞋会问,线下开发、测试环境,执行了一个DDL,发现很久都没有执行完,是不是被阻塞了?要怎么解决?包括在群里,也经常会碰到类似问题:DDL 被阻塞了,如何找到阻塞它的 SQL ?

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

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

[En]

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

  • 怎么判断一个DDL是不是被阻塞了 ?
  • 当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 呢?下面我们看看具体的定位方法。

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

针对上面这个Demo,我们看看sys.schema_table_lock_waits的输出。

只有一个 alter 操作,却产生了两条记录,而且两条记录的 Kill 对象还不一样,其中一条 Kill 的对象还是 alter 操作本身。如果对表结构不熟悉或不仔细看记录内容的话,难免会 Kill 错对象。不仅如此,在 DDL 操作被阻塞后,如果后续有 N 个查询被 DDL 操作堵塞,还会产生 N2 条记录。在定位问题时,这 N2 条记录完全是个噪音。这个时候,就需要我们对上述记录进行过滤了。过滤的关键是 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 就能发现。而第二类仅凭 show processlist 很难定位,因为未提交事务的连接在 show processlist 中的状态同空闲连接一样,都是 Sleep 。所以,网上有 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 才默认开启。

所以,在 MySQL 5.7 中,如果我们要使用 sys.schema_table_lock_waits ,必须首先开启 MDL 相关的 instrument。开启方式很简单,直接修改 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. It is recommended that you modify the configuration file synchronously.

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

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

  • *sys.schema_table_lock_waits

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

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

  • *Kill DDL 之前的会话

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

Original: https://www.cnblogs.com/xuliuzai/p/16411582.html
Author: 东山絮柳仔
Title: MySQL数据库 DDL 阻塞问题定位 【转载】

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

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

(0)

大家都在看

  • Java面试题(八)–Spring

    1 基础知识 1、说说你对Spring的理解? 1、Spring是一个开源框架,主要是为简化企业级应用开发而生。可以实现EJB可以实现的功能,Spring是一个IOC和AOP容器框…

    数据库 2023年6月16日
    085
  • Java面试题(九)–Spring MVC

    1、Spring MVC中的拦截器和Servlet中的filter有什么区别? 过滤器:依赖于servlet容器,在实现上基于函数回调,可以对几乎所有请求进行过滤 拦截器:依赖于w…

    数据库 2023年6月16日
    075
  • MySQL–用通配符进行过滤(LIKE操作符)

    1、LIKE操作符 怎样搜索产品名中包含文本anvil的所有产品?用简单的比较操作符肯定不行,必须使用通配符。利用通配符可创建比较特定数据的搜索模式。在这个例子中,如果你想找出名称…

    数据库 2023年6月16日
    083
  • pg小工:pgsql的介绍

    支持邮件列表 http://www.postgresql.org/community/lists/ Original: https://www.cnblogs.com/lyhabc…

    数据库 2023年6月9日
    0102
  • [Unity]如何将两个物体不留缝隙的精确贴合在一起

    比如说想让正方体精确贴合到墙上: 按住V,选中正方体,此时开启了 顶点吸附功能,正方体上的变换工具会变成以某个顶点为变换中心,如下图所示: 拖动中间的白色小方块,就会将正方体的该顶…

    数据库 2023年6月16日
    083
  • 手写LRU缓存淘汰算法

    概述 LRU算法全称为 Least Recently Used是一种常见的页面缓存淘汰算法,当缓存空间达到达到预设空间的情况下会删除那些 最久没有被使用的数据 。 常见的页面缓存淘…

    数据库 2023年6月11日
    0131
  • 【黄啊码】关于微信支付走过的坑

    错误:未定义数组索引:openid 。经过检查发现是 :微信支付授权获取 openId {“errcode”:40163,”errmsg&#82…

    数据库 2023年6月16日
    090
  • Matplotlib(基本用法)

    Matplotlib 是数据分析绘图的常见模块,可以算是 2D-绘图(Python)领域使用最广泛的套件,可以将数据图形化,并且提供多样化的输出格式,利于数据的显示并分析。 接下来…

    数据库 2023年6月16日
    097
  • MySQL学习(3)—MySQL常用命令

    ps:此随笔基于mysql 5.7.*版本。 准备 net start mysql 启动MySQL服务 net stop mysql 关闭MySQL服务 mysql [-h exi…

    数据库 2023年5月24日
    084
  • Mysql索引总结

    一、索引分类 Hash索引:Hash 索引查询效率很高,时间复杂度O(1)。Mysql Innodb引擎不支持hash索引的。Hash索引适合精确查找,不适合范围查找。 平衡二叉树…

    数据库 2023年5月24日
    065
  • 使用归并排序思想解决逆序对数量问题

    概述 归并排序算法,想必诸位都十分熟悉。其基本思想也就是 分治。整个排序过程分成两部分–分治法将问题 分(divide)成一些小的问题然后递归求解,而 治(conque…

    数据库 2023年6月11日
    095
  • window server2019+vmware16+Ubuntu20部署网站记录

    准备: 1:物理机一台,我的配置如下: 2:U盘10G以上一个,系统启动盘制作使用 3:Windows Server2019系统镜像 3-1:我下载的是server2019版本系统…

    数据库 2023年6月6日
    086
  • 新建Github仓库并上传本地代码

    按照Github的教程 Adding a local repository to GitHub using Git 1. 创建空的Github仓库 创建远程仓库 🔗 ,注意不要勾选…

    数据库 2023年6月14日
    0131
  • Java面试题(七)–Spring Boot

    1、Spring Boot提供了哪些核心功能?(高频) 1、jar包方式运行 通过引入spring-boot-maven-plugin插件可以将springboot项目打包成一个可…

    数据库 2023年6月16日
    089
  • 编程相关书单

    软工概论软件工程软件工程:实践者的研究方法 职业素养软技能码农翻身技术之瞳程序员修炼之道程序员的职业素养程序员的自我修养 程序设计计算机程序的构造和解释 (SICP) UML软件建…

    数据库 2023年6月11日
    079
  • 【Java框架】– SpringBoot大文件RestTemplate下载解决方案

    近期基于项目上使用到的RestTemplate下载文件流,遇到1G以上的大文件,下载需要3-4分钟,因为调用API接口没有做分片与多线程, 文件流全部采用同步方式加载,性能很慢。最…

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