MySQL 元数据锁及问题排查(Metadata Locks MDL)

"元数据"是用来描述数据对象定义的,而元数据锁(Metadata Lock MDL)即是加在这些定义上。通常我们认为非锁定一致性读(简单select)是不加锁的,这个是基于表内数据层面,其依然会对表的元数据加锁,保证读取数据期间表结构不会变更。

一、元数据锁简介

在事务执行过程中,MySQL会对所有涉及对象的定义加上元数据锁(语句执行的时候加锁),目的是保证事务执行过程中对象定义不被修改(你不能在别人查询的时候修改表结构或者把表删了)。

对表进行DML操作时(select, update等),MySQL会对表的定义施加一个共享元数据锁(S MDL),而进行DDL操作时,会施加排他元数据锁(X MDL)。DML之间的元数据锁时不会互相阻塞的,而普通用户通常只会执行DML,他们是感知不到元数据锁的。

如果DBA在业务运行期间执行了DDL,那么DDL也会尝试获取元数据锁,在事务都很短小的时候,可能很快就获取到了。但如果有长事务阻塞了DDL,那么就有可能导致严重的问题。

示例:在会话1中执行下面SQL:

create table t1 (id int primary key auto_increment);
begin;
select * from t1;

在这里插入图片描述

  • MySQL对DML默认是自动提交的,因此每条DML语句都是独立事务,当语句执行完,元数据锁就释放了,这里通过begin显式开启事务,让select语句执行完后,事务依然存在。

另启动一个会话2,执行下面DDL语句,可以发现其被阻塞(会话迟迟不返回):

alter table t1 add name varchar(16);

在这里插入图片描述

  • DDL在执行前会隐式提交事务并释放元数据锁,这就是为什么要另一个会话发起DDL。

启动会话3,执行show processlist;命令,即可看到会话2在等待元数据锁(Waiting for table metadata lock):

show processlist;

在这里插入图片描述

二、查看元数据锁

除了表,元数据锁也会加在表空间,存储过程,函数,触发器等对象上。但最常遇到的问题是我们想修改表结构,但是却被元数据锁阻塞了,导致DDL无法执行,进一步导致后续DML无法执行(业务停滞),此时需要进行人工干预。

2.1 查询元数据锁

MySQL提供了performance_schema.metadata_locks用来查询具体元数据锁信息,且默认就打开了元数据锁的信息收集,直接查询即可。表中包含了持有,等待及其他中间状态的MDL数据,当锁释放时,会从表中删除。

如果没有打开元数据锁信息收集,可以执行下面的SQL:

update performance_schema.setup_instruments
set enabled = 'YES', timed = 'YES'
where name = 'wait/lock/metadata/sql/mdl';

在这里插入图片描述
也可以持久化写入配置文件(需要重启):

[mysqld]
performance-schema-instrument='wait/lock/metadata/sql/mdl=ON'

我们依然用第1章的示例,在执行完会话1的SQL后,另开一个会话执行下面SQL:

select 
l.object_schema 数据库名,
l.object_type 对象类型, 
l.object_name 对象名称,
l.lock_type 锁类型,
l.lock_duration 持续类型,
l.lock_status 锁状态,
l.owner_thread_id 线程ID,
t.processlist_id 会话ID,
s.sql_text
from performance_schema.metadata_locks l
join performance_schema.threads t on t.thread_id=l.owner_thread_id
join performance_schema.events_statements_current s on s.thread_id=l.owner_thread_id
where l.object_schema='test'and l.object_name='t1';

在这里插入图片描述

  • 锁状态为granted,代表成功获取了元数据锁

随后执行会话2的DDL,再次执行查询SQL,可以看到锁状态pending(等待中):
在这里插入图片描述

  • 通过会话ID,锁状态和SQL_Text三个字段,可以判断会话ID为4107的select语句阻塞了alter table

2.2 常见问题

元数据锁的获取是有优先级的,X锁的优先级要高于S锁。在实际生产环境中,如果一个长事务阻塞了DDL,由于其尝试获取的是X锁(优先级高),那么它还会阻止后续DML获取S锁。即:DML => DDL阻塞 =>DML阻塞,从现象上看就是表无法执行任何操作。

在上面示例的基础上,再重新开几个会话执行下面的SQL,你会发现所有类型DML都无法返回(甚至无法读):

insert into t1 values(1,'Vincent');
update t1 set name='Victor' where id=1;
delete from t1 where id=1;
select * from t1;

在这里插入图片描述
如果生产环境出现了DDL阻塞,你的processlist可能就是下面的样子,堆积的DML会越来越多,最后挤爆线程:

show procelist;

在这里插入图片描述

解决方案:

  • 尽量避免在业务活跃期间执行DDL,特别是有长事务的时候
  • 如果已经产生了阻塞,立刻取消DDL或将其会话kill掉,先让业务运行下去

注:Online DDL在运行过程中也会短暂地获取X锁,所以并不能解决DDL阻塞问题。

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

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

相关文章

python中的类

_init_()函数 所有类都有一个名为__init__()的函数,它在每次使用类创建新对象时都会自动执行,可用于将用户指定的值在初始就赋给对象的属性,或者在创建对象时执行一些固定操作,如下: class Person:def __init__(self…

Python之Web开发初学者教程—ubuntu下vi的使用

Python之Web开发初学者教程—ubuntu下vi的使用 vi\vim 文本编辑器 i 切换到输入模式,以输入字符。 x 删除当前光标所在处的字符。 : 切换到底线命令模式,以在最底一行输入命令。 vi 保存并退出:esc键退出编辑-…

网络学习:Vlan原理

目录 一、交换机对数据帧的处理 1、Access: 2、Trunk: 3、Hybrid: 二、VLAN的划分方式 三、VLAN信息的传播技术(MVRP协议) 1、VLAN动态注册背景: 2、MVRP技术: 3、MVRP注意点&#xff…

前缀和与差分——练习(一维+二维)

一、前言 前缀和与差分算是很常用的算法,熟记是有必要的。 ——题目来源y总每日一题,感觉正适合模板分块讲解系列。 二、浅谈 我们可以用a数组作为前缀和数组,b数组作为差分数组,因为二者互为逆运算。 他们常常用做优化&#xff…

Python爬虫——Selenium

简介 Selenium是一个自动化测试框架,可以通过编程语言控制浏览器进行各种操作。在Python中,可以使用Selenium实现爬虫。 首先,我们需要需要安装Selenium库。可以使用pip命令安装: pip install selenium要使用的话我们还需…

7-Zip:一款免费开源但强大的压缩软件

名人说:莫道桑榆晚,为霞尚满天。——刘禹锡(刘梦得,诗豪) 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 目录 一、什么是7-zip?①为什么选择7-Zip?②7-Zip的主要特点二、下载安装三、如何使用7-Zip?四、总结很高兴你打开了这篇博客,如有疑问,欢迎评论…

密码学之椭圆曲线

引言 DH(Diffie-Hellman)密钥交换算法于1976年提出,是第一个公开密钥交换算法。其基础是数学中的群论,群论也是大多数公开密钥密码的基础。简单来说,群是一组元素的集合以及在这些元素上定义的特殊二元运算。 一个群需要满足如下性质: 封闭性:群中两个元素的运算结果仍…

用于生成环境噪声的Noisedash

本文中关于音频的专业描述,来自于互联网和 ChatGPT; 什么是白噪声 ? 白噪声(White Noise)是具有平均功率的随机信号,其功率在整个频谱范围内均匀分布。它的能量在所有频率上都是相等的,没有频率…

【Linux C | 网络编程】广播概念、UDP实现广播的C语言例子

😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀 🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C、数据结构、音视频🍭 🤣本文内容🤣&a…

代码随想录算法训练营第33天—动态规划01 | ● 理论基础 ● 509. 斐波那契数 ● 70. 爬楼梯 ● 746. 使用最小花费爬楼梯

动态规划理论基础 https://programmercarl.com/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html 视频:https://www.bilibili.com/video/BV13Q4y197Wg 主要题型 动规基础题 斐波那契数列 背包问题打家劫舍股票问题子序列问题 解题…

伟大音乐家的伟大不朽作品,贝多芬一生的音乐作品全集

一、音乐描述 贝多芬一生创作题材广泛,重要作品包括9部交响曲、1部歌剧、32首钢琴奏鸣曲、5首钢琴协奏曲、多首管弦乐序曲及小提琴、大提琴奏鸣曲等。因为其对古典音乐的重大贡献,以及对奏鸣曲式和交响曲套曲结构的发展和创新,而被后世尊称为…

【比较mybatis、lazy、sqltoy、mybatis-flex、easy-query、mybatis-mp操作数据】操作批量新增、分页查询(四)

orm框架使用性能比较 比较mybatis、lazy、sqltoy、mybatis-flex、easy-query、mybatis-mp操作数据 环境: idea jdk17 spring boot 3.0.7 mysql 8.0测试条件常规对象 orm 框架是否支持xml是否支持 Lambda对比版本编码方式mybatis☑️☑️3.5.4lambda xml 优化sq…

【记录31】elementUI el-tree 虚线、右键、拖拽

父组件 <eltree :treeData"treeData"></eltree>import eltree from "../../components/tree.vue"; export default {name: ,components: { // org_tree ,eltree},watch: {},data() {return {orgFormchoose: {},orgForm: { type: 0, limits: 1…

Python乱码恢复

比如说网页是ISO-8859-1编码&#xff0c;然后requests得到的是乱码&#xff0c; 那么这样操作就可以还原数据&#xff1a;res.text.encode(‘ISO-8859-1’).decode(‘utf-8’) 乱码恢复网站&#xff0c;可以知道是什么编码http://www.mytju.com/classCode/tools/messyCodeReco…

CRC8/CRC16/CRC32全面对比详解

在现代数据通信和存储技术中&#xff0c;CRC&#xff08;Cyclic Redundancy Check&#xff0c;循环冗余校验&#xff09;算法作为一种关键的错误检测机制&#xff0c;在确保数据完整性方面扮演着不可或缺的角色。该算法基于一个特定的生成多项式对原始数据块进行模2除法运算&am…

Stable Diffusion——Animate Diff一键AI图像转视频

前言 AnimateDiff 是一个实用框架&#xff0c;可以对文本生成图像模型进行动画处理&#xff0c;无需进行特定模型调整&#xff0c;即可为大多数现有的个性化文本转图像模型提供动画化能力。而Animatediff 已更新至 2.0 版本和3.0两个版本&#xff0c;相较于 1.0 版本&#xff…

Golang关键字defer

# Golang 关键字 defer 的用法和原理## 什么是 defer在 Golang 中&#xff0c;有一个特殊的关键字 defer&#xff0c;它可以让一个函数或者语句在当前函数返回之前执行。defer 的常见用途有&#xff1a;- 关闭文件、数据库连接、网络连接等资源 - 解锁互斥锁 - 捕获和处理异常 …

C#高级:Winform桌面开发中DataGridView的详解

一、每条数据增加一个按钮&#xff0c;点击输出对应实体 请先确保正确添加实体的名称和文本&#xff1a; private void button6_Click(object sender, EventArgs e) {//SQL查询到数据&#xff0c;存于list中List<InforMessage> list bll.QueryInforMessage();//含有字段…

代码思想录-动态规划(509. 斐波那契数、70. 爬楼梯、746. 使用最小花费爬楼梯)

509. 斐波那契数 class Solution { public:int fib(int n){if (n0) return 0;if (n1) return 1;vector<int> dp(n1, 0);dp[0] 0;dp[1] 1;for (int i2; i<n1;i){dp[i] dp[i-1] dp[i-2];}return dp[n];} }; 70. 爬楼梯 class Solution { public:int climbStairs(…

Linux删除Mysql

//rpm包安装方式卸载 查包名&#xff1a;rpm -qa|grep -i mysql 删除命令&#xff1a;rpm -e –nodeps 包名//yum安装方式下载 1.查看已安装的mysql 命令&#xff1a;rpm -qa | grep -i mysql 2.卸载mysql 命令&#xff1a;yum remove mysql-community-server-5.6.36-2.el7.x86…