【第26天】SQL进阶-查询优化- performance_schema系列实战二:锁问题排查(MDL锁)(SQL 小虚竹)

news2024/12/25 9:01:53

回城传送–》《32天SQL筑基》

文章目录

  • 零、前言
  • 一、什么是MDL锁
  • 二、什么时候适合加MDL锁
  • 三、 实战演练
    • 3.1 数据准备(如果已有数据可跳过此操作)
    • 3.2 开启第一个会话,显式开启一个事务,并执行一个update语句不提交
    • 3.3 开启第二个会话,对sbtest1表执行DDL语句添加一个普通索引
    • 3.4 开启第三个会话,查询线程信息
    • 3.5 分析
    • 3.6 提交第一个会话的事务
  • 四、总结
  • 五、参考

零、前言

今天是学习 SQL 打卡的第 26 天,每天我会提供一篇文章供群成员阅读( 不需要订阅付钱 )。

希望大家先自己思考,如果实在没有想法,再看下面的解题思路,自己再实现一遍。在小虚竹JAVA社区 中对应的 【打卡贴】打卡,今天的任务就算完成了,养成每天学习打卡的好习惯。

​ 虚竹哥会组织大家一起学习同一篇文章,所以有什么问题都可以在群里问,群里的小伙伴可以迅速地帮到你,一个人可以走得很快,一群人可以走得很远,有一起学习交流的战友,是多么幸运的事情。

​ 我的学习策略很简单,题海策略+ 费曼学习法。如果能把这些题都认认真真自己实现一遍,那意味着 SQL 已经筑基成功了。后面的进阶学习,可以继续跟着我,一起走向架构师之路。

今天的学习内容是:SQL进阶-查询优化- performance_schema系列实战二:锁问题排查(MDL锁)

一、什么是MDL锁

表级锁有两种,一种是针对于表记录数据的锁,另外一种就是MDL(metadata lock)的锁,它是基于表元数据(表结构)的锁,MDL锁是为了保证并发环境下元数据和表数据的结构一致性。如果有其它事务对表加了MDL锁,那么其它事务就不能对表结构进行变更,同样对于正在进行表结构变更的时候也不允许其它事务对表数据进行增删改查。

二、什么时候适合加MDL锁

MDL读锁:在我们对表数据进行增删改查的的时候都需要对表加MDL读锁。

MDL写锁:当我们对表结构进行修改的时候会加MDL写锁。

三、 实战演练

当使用show processlist; 语句查看线程时,发现State列为“Waiting for table metadata lock” ,这种情况就是要去排查谁持有了MDL锁没释放。
下面我们尝试着进行MDL锁等待场景模拟(mdl锁记录对应的instruments为wait/lock/metadata/sql/mdl,默认未启用,对应的consumers为performance_schema.metadata_locks,在setup_consumers只受全局配置项global_instrumentation控制,默认启用)。

3.1 数据准备(如果已有数据可跳过此操作)

使用sysbench准备初始化数据
创建测试数据库sysbenchdemo

create database sysbenchdemo;

在这里插入图片描述
准备测试数据:

sysbench /usr/share/sysbench/oltp_insert.lua \
--mysql-host=localhost \
--mysql-port=3306 \
--mysql-socket=/tmp/mysql.sock \
--mysql-user=root \
--mysql-password=xiaoxuzhu \
--mysql-db=sysbenchdemo \
--db-driver=mysql \
--tables=8 \
--table-size=100000 \
--time=180 prepare

在这里插入图片描述

3.2 开启第一个会话,显式开启一个事务,并执行一个update语句不提交

登录mysql数据库

use sysbenchdemo;

在这里插入图片描述

查询以下加锁线程的process id,以便后续排查过程好对应

select connection_id();

在这里插入图片描述

开启事务

 begin;

执行一个update语句,不提交

select * from sbtest1 limit 1;
update sbtest1 set pad='yyy' where id=1;

在这里插入图片描述

3.3 开启第二个会话,对sbtest1表执行DDL语句添加一个普通索引

登录mysql数据库

use sysbenchdemo;

在这里插入图片描述

查询线程的process id,以便后续排查过程好对应

select connection_id();

在这里插入图片描述

alter table sbtest1 add index index_c(c); 

在这里插入图片描述
发现执行ddl语句被阻塞了。

3.4 开启第三个会话,查询线程信息

show processlist;

在这里插入图片描述

从Info 字段知道是哪个语句出了问题。

可发现刚才执行的添加索引的语句,被阻塞住。

Waiting for table metadata lock

其中OWNER_THREAD_ID: # 持有锁的内部线程ID

查看process id为 12442,12443 各自对应的内部线程ID是多少

select sys.ps_thread_id(12442);

在这里插入图片描述

process id=12442 的线程对应的内部线程ID正好为12606

select sys.ps_thread_id(12443);

在这里插入图片描述

process id=12443 的线程对应的内部线程ID正好为12607

3.5 分析

通过查询performance_schema.metadata_locks表得知MDL锁信息

select * from performance_schema.metadata_locks where OWNER_THREAD_ID!=sys.ps_thread_id(connection_id());

在这里插入图片描述

如下就是MDL相关的锁模式,以及对应的SQL语句

锁模式对应SQL
MDL_INTENTION_EXCLUSIVEGLOBAL对象、SCHEMA对象操作会加此锁
MDL_SHAREDFLUSH TABLES with READ LOCK
MDL_SHARED_HIGH_PRIO仅对 MyISAM 存储引擎有效
MDL_SHARED_READSELECT查询
MDL_SHARED_WRITEDML语句
MDL_SHARED_WRITE_LOW_PRIO仅对MyISAM存储引擎有效
MDL_SHARED_UPGRADABLEALTER TABLE
MDL_SHARED_READ_ONLYLOCK xxx READ
MDL_SHARED_NO_WRITEFLUSH TABLES xxx,yyy,zzz READ
MDL_SHARED_NO_READ_WRITEFLUSH TABLE xxx WRITE
MDL_EXCLUSIVEALTER TABLE xxx PARTITION BY …

从图上可知,LOCK_TYPE 为SHARED_WRITE的12606 内部线程持有MDL锁。
有sysbenchdemo.sbtest1表的SHARED_UPGRADABLE、EXCLUSIVE锁,其中SHARED_UPGRADABLE处于GRANTED状态,EXCLUSIVE处于PENDING状态

在这里插入图片描述
说明内部线程12607 在等待MDL锁。

通过show processlist语句的查询结果
在这里插入图片描述

可以看出process id为12442 的线程已经长时间处于sleep状态。但不知道执行了什么语句。

确认一下线程是否存在着一个没有提交的事务。

select * from information_schema.innodb_trx;

在这里插入图片描述

从查询结果可知,确实这个process id为12442 的线程有一个没有提交的事务,但还是不知道执行了什么语句。

临时解决方案:kill 12442 的线程

永久解决方案还是要找出执行了什么语句。
通过performance_schema.events_statements_current表来查询某个线程正在执行或者说最后一次执行完成的语句事件信息。

select * from performance_schema.events_statements_current where thread_id=12606;

在这里插入图片描述

通过SQL_TEXT字段我们可以清晰地看到该线程正在执行的SQL语句是什么。
注意:performance_schema.events_statements_current表的信息不一定可靠,因为该表中对于每个线程只能记录当前正在执行和最近一次执行完成的语句事件信息,一旦这个线程执行新的语句,信息就会被覆盖。

要保证是最可靠的,可以去查看events_statements_history 表,events_statements_history表包含每个线程最新的N个语句事件。

select * from performance_schema.events_statements_history  where thread_id=12606;

在这里插入图片描述
在这里插入图片描述

3.6 提交第一个会话的事务

commit;

在这里插入图片描述

第二个会话被阻塞的语句也顺利执行了。
在这里插入图片描述

在第三个会话中查看线程情况

show processlist;

在这里插入图片描述
从图上结果可知,MDL锁被释放了。

四、总结

通过本文学习,学会了什么是MDL锁以及MDL锁的适用场景,通过实战演练排查MDL锁问题,从理论到实战的介绍,可以加深对MDL锁的理解。

五、参考

应用示例荟萃 | performance_schema全方位介绍(上)
技术分享 | MySQL 的 MDL 锁解惑
SQL进阶-查询优化- performance_schema系列三:事件记录(SQL 小虚竹)

我是虚竹哥,我们明天见~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/183196.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

机器自动翻译古文拼音 - 十大宋词 - 水调歌头 明月几时有 苏轼

水调歌头明月几时有 北宋苏轼 明月几时有,把酒问青天。 不知天上宫阙,今夕是何年。 我欲乘风归去,又恐琼楼玉宇,高处不胜寒。 起舞弄清影,何似在人间? 转朱阁,低绮户,照无眠。 不应…

idea 配置tomcat 运行jsp项目

1、复用idea打开jsp项目 2、添加tomcat配置 3、点击后会出现配置框,这里画框的地方都选上,版本选择1.8,其他的信息内容默认后,点击确认 4、点击 File->Project Structure,弹出界面选择Project,这里sdk选择1.8,语言选…

#7反转链表#

反转链表 1题目链接 链接 2思路 思路1(暴力): 定义两个指针或者三个指针 这里选择三个指针 清晰一点 头部 头部的下一个 头部的下一个的下一个 n1 n2 n3 做好n2和n1的连接: n2->nextn1 然后: n2n1 n3n2 n3n3->next 相当于三个指针都往…

JAVA混合使用函数式接口(BiPredicate和Consumer)、泛型、lambda表达式、stream流,优化List求交集和差集后的通用处理

文章目录前言项目场景两个List求交集和差集BiPredicate和Consumer基本介绍优化目标一步步优化代码最后前言 本文主要讲的是一个小的功能代码的优化案例,用到的知识点主要包括函数式接口(BiPredicate和Consumer)、泛型、lambda表达式、stream…

100天精通Python(数据分析篇)——第73天:Pandas文本数据处理方法之查找、替换、拼接、正则、虚拟变量

文章目录每篇前言一、Python字符串内置方法1. 文本查找2. 文本替换3. 文本拼接4. 正则提取二、Pandas实现文本查找1. str.startswith(字符串)2. str.endswith(字符串)3. str.index(字符串, start0, endlen(string))4. str.rindex(字符串, start0, endlen(string))5. str.find(字…

工具技巧和读文档 | 读函数式编程接口文档 | 匿名内部类 | lambda表达式 |IDEA

Function接口,函数式接口 按入参返回值分类,大概分为4种类型,再加上多个入参就又多了Bi开头的两种。 有CtrlP的时候不懂参数列表该写啥,就先CtrlALT看下入参类型的相关实现类! 一些实用的快捷键:Ctrl P看参…

AORT:一款功能强大的多合一网络侦查与数据收集工具

关于AORT AORT是一款功能强大的多合一网络侦查与数据收集工具,该工具的主要目的是帮助漏洞Hunter和渗透测试人员完成网络侦查环节的各类任务。AORT基于Python开发,使用起来非常简单且方便,并且支持跨平台(只要安装了Python 3即可…

怒删虚拟机,FPGA开发新宠-几步在Windows上安装桌面化Linux

Linux上运行Vivado这类EDA工具要比Window上快很多,大概就是优化的问题,所以选择Linux上开发是一个比较好的选择(主要是免费)。国内习惯了Win系统,所以用Linux比较少,那么有没有既可以在Windows上做一些文档…

Python爬虫(4)-Selenium模拟鼠标操作

在Selenium4.2以后的版本里面鼠标的操作方法都封装在了ActionChains中需要时直接取即可。 1.鼠标双击 使用方法就是调用ActionChains然后传入你需要点击的按钮的位置即可 ActionChains(driver).double_click(f1).perform() perform()的意思就是执行所有ActionChains中的动作 …

python字典应用

python字典应用 文章目录python字典应用一、实验目的二、实验原理三、实验环境四、实验内容五、实验步骤字典的综合案例使用collections模块的defaultdict类来实现创建字典。拓展知识一:内置函数globals()和locals()拓展知识二:有序字典 collections.Ord…

如何使用MyBatis简化JDBC开发?MyBatis持久层框架快速入门

文章目录1. 前言2. JDBC 存在的缺点3. MyBatis 优化4. MyBatis 快速入门5. 总结Java编程基础教程系列1. 前言 JavaEE 企业级 Java 项目中的经典三层架构为表现层,业务层和持久层,使用Java 代码操作数据库属于持久层内容,而 MyBatis 对 JDBC …

Multus k8s网络浅谈

Multus是什么 k8s不提供网络解决方案,提供CNI ( Container Networking Interface )规范,被CNI插件遵守(Flannel, Calico,Multus等,这些是网络方案) Multus 提供了将多个接口添加到pod的功能 Flannel 为每…

实现自己的数据库三

一 前言上篇实现了数据库的持久化,就是一个质的飞跃,虽然代码不复杂,但是对没有这方面经验者来说,还是意思的,下一步就是要完成另外一个飞跃,将存储的数据结构采用B树的形式来保存。在改造之前,…

为什么要设计非公平锁?

背景 公平:排队 非公平:在合适时机插队 非公平还是 ReentrantLock 的默认策略,排队时间不浪费了? 场景 来看这种场景 假如A持有一把锁,B请求这把锁,这时候B被挂起进入阻塞,A释放锁的时候&a…

点与线段的关系

点与线段的关系 对于向量a(x1,y1)和b(x2,y2) 点乘的数学意义:a * b x1x2 y1y2 点乘的几何意义:a * b |a||b|cosQ 这个可以看成是投影关系表达式:cosQ a * b / ( |a||b|) 令r cosQ; 求p点和线段AB的位置关系,可以…

将字符串根据指定的分隔符拆分为元组str.partition()

【小白从小学Python、C、Java】 【计算机等级考试500强双证书】 【Python-数据分析】 将字符串根据指定的分隔符拆分为元组 str.partition() 选择题 对于以下python代码最后输出的结果是? string "I Love Python" print("【显示】string.partition(Love)"…

Unity3d 微信小程序(小游戏)项目实现流量主接入功能(含源码)

前言 很早之前编写了Unity导出微信小游戏的博客,也尝试自己做了个Demo上线了,基本没更新过,不过几个月的时间,用户超过了一千,可以开通流量主了,大概率是因为上篇的帖子浏览量大了,扫码体验的人…

Aurora、Chip2chip、Ethernet(二)

摘要:Aurora、Chip2chip、Ethernet共用一个gt时钟的正确的解决方案以及在实际实现以及在实现过程中遇到的其它的问题。 我在实际中遇到的困难如下: 现在需要将三个ip共用一对GT时钟,一个Ethernet IP,一个Ethernet IP&#xff08…

每日学术速递1.29

CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 Subjects: cs.CV 1. Compact Transformer Tracker with Correlative Masked Modeling 标题:带有相关掩码建模的紧凑型变压器跟踪器 作者: Zikai Song, Run Luo, Junqing Yu, Y…

GLM国产大模型训练加速:性能最高提升3倍,显存节省1/3,低成本上手

作者|BBuf、谢子鹏、冯文 2017 年,Google 提出了 Transformer 架构,随后 BERT 、GPT、T5等预训练模型不断涌现,并在各项任务中都不断刷新 SOTA 纪录。去年,清华提出了 GLM 模型(https://github.com/THUDM…