有了MDL锁视图,业务死锁从此一目了然
摘要:MDL锁视图让一线运维人员清晰地查看数据库各session持有和等待的元数据锁信息,从而找出数据库MDL锁等待的根因,准确地进行下一步决策。
当多用户共同存取数据时,数据库中就会产生多个事务同时存取同一数据的情况。若不控制这种并发操作,数据库的一致性就会被破坏。这种情况下,加锁是实现数据库并发控制的关键技术。
举个例子,加锁后事务就对该数据对象有了一定的控制,在事务释放锁之前,其他的事务不能对此数据对象进行更新操作。
MySQL从 5.5版本开始引入MDL锁(即元数据锁),MDL锁主要为了保证元数据的一致性(主要是保证DDL操作与DML操作之间的一致性),用于处理不同线程操作同一元数据对象的同步与互斥问题,在各个业务场景中会十分频繁地使用到。
具体而言,MySQL引入MDL锁可以解决如下问题:一是事务隔离问题,比如在可重复读隔离级别下,会话A在2次查询期间,会话B对表结构做了修改,2次查询结果就会不一致,无法满足可重复读的要求。二是数据复制问题,比如会话A执行了多条更新语句期间,另外一个会话B做了表结构变更并且先提交,就会导致slave在重做时,先重做alter,再重做update时就会出现复制错误的现象。
MDL锁视图,一目了然元数据锁问题
社区版MySQL无法获取表MDL锁的详细信息,当客户遇到类似“Waiting for metadata lock”的问题而阻塞DML或DDL后,由于无法确定各session之间的关联,往往无从下手,复杂情况下,只能重启实例,从而增加解决问题的成本,对业务产生较大影响。
而且在业务场景较复杂的情况下,一旦涉及对数据库元数据的互斥操作(如DDL、LOCK Table等),此类问题便会频繁发生,给一线运维和客户带来很大的困扰。
针对以上痛点,华为云数据库MySQL在充分调研内核的基础上,推出了MDL锁视图特性,可以清晰查看数据库各session持有和等待的元数据锁信息,方便现网运维进行问题定位,有效进行系统诊断,帮助客户更好地优化自身业务。
MDL锁视图以系统表的形式呈现,该表位于INFORMATION_SCHEMA,表名:METADATA_LOCK_INFO,表结构如下:
MDL锁视图主要由7个字段组成,各字段详情为:
- THREAD_ID:session的ID,即会话ID
- LOCK_STATUS:MDL锁的状态,主要分为PENDING和GRANTED两种,分别表示session正在等待该MDL锁和session已获得该MDL锁
- LOCK_MODE:加锁的模式,如MDL_SHARED 、MDL_EXCLUSIVE 、MDL_SHARED_READ、MDL_SHARED_WRITE等
- LOCK_TYPE:MDL锁的类型,如Table metadata lock、Schema metadata lock、Global read lock、Tablespace lock等
- LOCK_DURATION:MDL锁的范围,有三种取值:MDL_STATEMENT、MDL_TRANSACTION、MDL_EXPLICIT,分别表示语句级别、事务级别、global级别
- TABLE_SCHEMA:数据库名,对于部分global级别的MDL锁,该值为空
- TABLE_NAME:表名,对于部分global级别的MDL锁,该值为空
MDL锁视图好在哪?
下面通过两则案例来对MDL锁视图进行进一步的说明。
场景一:长时间未提交事务,阻塞DDL,继而阻塞所有同表的操作
客户发现表t2的truncate一直被阻塞后,业务流程中对表t2的select操作也全部被阻塞。DDL被阻塞后,客户立刻执行show processlist:
但是通过processlist信息,只能看到session 4执行truncate操作时被其他session持有的table metadata lock阻塞,session 5执行select操作时也同样被阻塞,无法确定哪个session阻塞了session 4和session 5。此时,如果盲目的去kill其他session(2或3)会给线上业务带来很大风险,因此只能等待其他session释放该MDL锁。
而当客户引入MDL锁视图后,执行SELECT * FROM INFORMATION_SCHEMA.METADATA_LOCK_INFO:
结合show processlist的结果,从元数据锁视图中可以明显看出,session 4 pending在表t2的metadata lock,session 3持有表t2的metadata lock,该MDL锁为事务级别,只要session 3的事务不提交,session 4便会一直阻塞。因此,客户只需要在session 3中执行commit或kill session 3,便可以让业务继续运行。
场景二:长时间持有MDL锁,导致全备失败
客户实例最近几次全备均失败,但是业务表现似乎正常,而且最近系统业务量不高,未出现明显问题。运维团队发现全备被阻塞后,立刻show processlist,发现有多个活跃的用户session:
全备是基于xtrabackup,在执行真正的备份之前需要执行lock tables for backup,但从show processlist中只能看到:lock tables for backup时一直被某个MDL锁阻塞,全备超时失败;客户的多个session业务量很小,都处于sleep状态,于是客户继续执行show open tables where in_use >=1:
发现有个表t1始终处于in use状态,所以猜测是用户某个session持有了该表t1的MDL锁未释放,导致lock tables for backup等待超时。但是结合show processlist仍然无法确定是哪个session持有表t1的MDL锁,想让全备执行成功,只能通知客户逐一断连session或者重启实例。
引入MDL锁视图后,客户执行SELECT * FROM INFORMATION_SCHEMA.METADATA_LOCK_INFO:
结合show processlist的结果,从元数据锁视图中可以明显看出,session 4 pending在全局backup lock上;session 2持有全局的backup lock,该MDL锁类型为MDL_EXPLICIT,global级别。因此,客户只需要在session 2显式调用unlock tables释放锁或者kill session 2即可让业务继续运行。
通过以上两个案例,MDL锁视图的重要性不言而喻,它可以让客户和一线运维人员清晰地查看数据库各session持有和等待的元数据锁信息,从而找出数据库MDL锁等待的根因,准确地进行下一步决策,有效降低对业务的影响。
华为云数据库MySQL在828企业上云节期间,还有众多优惠活动,体验MDL锁视图的最佳时机。
有了MDL锁视图,业务死锁从此一目了然的更多相关文章
- 【锁】Oracle死锁(DeadLock)的分类及其模拟
[锁]Oracle死锁(DeadLock)的分类及其模拟 1 BLOG文档结构图 2 前言部分 2.1 导读和注意事项 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不 ...
- MySQL锁等待与死锁问题分析
前言: 在 MySQL 运维过程中,锁等待和死锁问题是令各位 DBA 及开发同学非常头痛的事.出现此类问题会造成业务回滚.卡顿等故障,特别是业务繁忙的系统,出现死锁问题后影响会更严重.本篇文章我们一起 ...
- mysql 原理 ~ DDL之mdl锁
一 简介: MDL锁 二 具体 1 MDL锁 1 增删查改 申请MDL读锁 2 ddl语句 1. 拿MDL写锁 2. 降级成MDL读锁 3. 真正做DDL ...
- LiteOS:SpinLock自旋锁及LockDep死锁检测
摘要:除了多核的自旋锁机制,本文会介绍下LiteOS 5.0引入的LockDep死锁检测特性. 2020年12月发布的LiteOS 5.0推出了全新的内核,支持SMP多核调度功能.想学习SMP多核调度 ...
- 整理分布式锁:业务场景&分布式锁家族&实现原理
1.引入业务场景 业务场景一出现: 因为小T刚接手项目,正在吭哧吭哧对熟悉着代码.部署架构.在看代码过程中发现,下单这块代码可能会出现问题,这可是分布式部署的,如果多个用户同时购买同一个商品,就可能导 ...
- MySQL锁系列3 MDL锁
http://www.cnblogs.com/xpchild/p/3790139.html MySQL为了保护数据字典元数据,使用了metadata lock,即MDL锁,保证在并发的情况下,结构 ...
- MDL锁
mdl锁的主要作用是用来维护表元数据的一致性.在表上有活动事务的时候,不可以对表元数据进行修改操作. 如果没有MDL锁的保护,那么session2可以直接执行,并导致session1出错. MDL锁是 ...
- Oracle死锁一例(ORA-00060),锁表导致的业务死锁问题
1.问题发现 检查客户数据库的时候发现存在大量死锁的情况 Thread advanced to log sequence (LGWR switch) Current log# mem# : /orad ...
- redis 设置分布式锁要避免死锁
1. jedis 中 setnx key value 虽然可以处理同步问题 (setnx 有返回值 1是key不存在把它设置进去,0是key已经存在了)但是 setnx设置完后 程序的下一步 有可能挂 ...
随机推荐
- TCP 客户端
""" 创建客户端 绑定服务器ip地址和端口号(端口号是整型) 与服务器建立连接 发送给服务器要发送的数据(转码) 接收服务器返回的数据 关闭客户端 "&quo ...
- SET DYNAMICS 365 COLORS AND LOGO USING THEMES
https://carldesouza.com/dynamics-365-colors-logo-themes/ BEFORE WE START, I NEED YOUR HELP. I AM SPE ...
- Docker管理工具之portainer
参考:https://www.cnblogs.com/frankdeng/p/9686735.html 1. 查询portainer镜像 命令:docker search portainer 实例: ...
- 移动物体监控系统-sprint4嵌入式web服务器开发
一.BOA嵌入式服务器的移植 step1:下载BOA服务器并解压,进入boa下面的src目录,执行./configure生成必须的配置文件以及Makefile step2:修改Makefile文件 c ...
- python4.3内置函数
常见的内置函数 a=[12,31,31,232,34,32,43,54,36]max1=max(a)#最大函数print(max1)min1=min(a)#最小函数print(min1)sum1=su ...
- 一文说通C#中的异步编程补遗
前文写了关于C#中的异步编程.后台有无数人在讨论,很多人把异步和多线程混了. 文章在这儿:一文说通C#中的异步编程 所以,本文从体系的角度,再写一下这个异步编程. 一.C#中的异步编程演变 1. ...
- Python使用pyexecjs代码案例解析
针对现在大部分的网站都是使用js加密,js加载的,并不能直接抓取出来,这时候就不得不适用一些三方类库来执行js语句 execjs,一个比较好用且容易上手的类库(支持py2,与py3),支持 JS ru ...
- pageHelper使用时的注意点
1 在pom.xml中导入相关的依赖(注意版本问题,报错十有八九是因为版本问题) <dependency> <groupId>com.github.pagehelper< ...
- 使用Luhn算法实现信用卡号验证
问题描述: 2:信用卡号的验证 [信用卡号的验证] 当你输入信用卡号码的时候,有没有担心输错了而造成损失呢?其实可以不必这么 担心,因为并不是一个随便的信用卡号码都是合法的,它必须通过 Luhn 算法 ...
- html定时跳转页面
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...