快速定位业务死锁 -- 表MDL锁视图

举报
dbin_mu 发表于 2020/06/30 14:28:07 2020/06/30
【摘要】 MDL锁,Metadata Lock,即元数据锁,在数据库中元数据即数据字典信息包括db, table, function, procedure, trigger, event等。MDL锁主要为了保证元数据的一致性,用于处理不同线程操作同一元数据对象的同步与互斥问题,会在各个业务场景下十分频繁地使用到。

什么是MDL

MDL锁,Metadata Lock,即元数据锁,在数据库中元数据即数据字典信息包括db, table, function, procedure, trigger, event等,首先,看看官方的说法:

MySQL uses metadata locking to manage concurrent access to database objects and to ensure data consistency. Metadata locking applies not just to tables, but also to schemas, stored programs (procedures, functions, triggers, scheduled events), tablespaces, user locks acquired with the GET_LOCK() function, and locks acquired with the locking service.

从上面的描述可以看到,MDL锁主要为了保证元数据的一致性,用于处理不同线程操作同一元数据对象的同步与互斥问题,会在各个业务场景下十分频繁地使用到。

MySQL5.5.3版本引入了MDL锁。其实5.5也有类似元数据保护的机制,但没有明确提出MDL的概念。5.5之前版本(比如5.1)5.5之后版本在元数据保护上的不同点是,5.1对于元数据的保护是语句级别的,5.5对于Metadata的保护是事务级别的。所谓语句级别,即语句执行完成后,无论事务是否提交或回滚,其表结构可以被其他会话更新;而事务级别则是在事务结束后才释放MDL

引入MDL锁主要是为了解决两个问题:

Ø  事务隔离问题:比如在可重复隔离级别下,会话A2次查询期间,会话B对表结构做了修改,两次查询结果就会不一致,无法满足可重复读的要求。

Ø  数据复制问题:比如会话A执行了多条更新语句期间,另外一个会话B做了表结构变更并且先提交,就会导致slave在重做时,先重做alter,再重做update时就会出现复制错误的现象。

什么是MDL锁视图

社区版MySQL无法获取表元数据锁(MDL)的详细信息,当客户遇到类似“Waiting for metadata lock”的问题而阻塞DMLDDL后,由于无法确定各session之间的关联关系,往往无从下手,复杂情况下,只能重启实例,解决问题的成本非常高,会对业务产生较大影响。且在业务场景较复杂的情况下,一旦涉及对数据库元数据的互斥操作(如DDLLOCK Table等),此类问题便会频繁发生,给一线运维和客户带来很大的困扰。

针对以上痛点,华为云数据库MySQL在充分调研内核的基础上,推出了MDL锁视图特性,可以查看数据库各session持有和等待的元数据锁信息,一目了然,方便现网运维进行问题定位,更好的服务客户;对于客户而言,可以有效进行系统诊断,优化自身业务。

MDL锁视图详解

         MDL锁视图以系统表的形式呈现,该表位于INFORMATION_SCHEMA,表名:METADATA_LOCK_INFO。表结构如下:

         image.png

各字段详情:

Ø  THREAD_IDsessionid,即会话id

Ø  LOCK_STATUSMDL锁的状态,两种:PENDINGGRANTED,分别表示session正在等待该MDL锁和session已获得该MDL锁;

Ø  LOCK_MODE:加锁的模式,如:MDL_SHARED MDL_EXCLUSIVE MDL_SHARED_READMDL_SHARED_WRITE等;

Ø  LOCK_TYPEMDL锁的类型,如:Table metadata lockSchema metadata lockGlobal read lockTablespace lock等;

Ø  LOCK_DURATIONMDL锁范围,三种取值:MDL_STATEMENTMDL_TRANSACTIONMDL_EXPLICIT,分别表示语句级别、事务级别、global级别;

Ø  TABLE_SCHEMA:数据库名,对于部分global级别的MDL锁,该值为空;

Ø  TABLE_NAME:表名,对于部分global级别的MDL锁,该值为空;

 

备注:关于LOCK_MODELOCK_TYPE的详情这里不一一列举,感兴趣的读者可自行查阅。

典型案例

以下案例均源于现网真实案例。

场景一 长时间未提交事务,阻塞DDL,继而阻塞所有同表的操作

场景再现:

T

Session 2

Session 3

Session 4

Session 5

T1

begin;

select *from t1;




T2


begin;

select *from t2;



T3



truncate table t2;

(blocked)


T4




begin;

select *from t2;

(blocked)

客户问题:

客户发现对表t2truncate一直被阻塞后,且业务流程中对表t2SELECT操作也全部被阻塞。

问题排查过程:

Ø  MDL锁视图

当用户发现DDL被阻塞后,执行show processlist

image.png

但是通过processlist信息,只能看到:

l  session 4执行truncate操作时被其他session持有的table metadata lock阻塞;

l  session 5执行select操作时也同样被阻塞;

l  无法确定哪个session23?)阻塞了session 4session 5

此时,盲目的去kill其他session23)会给线上业务带来很大风险,因此只能等待其他session释放该MDL锁。

Ø  引入MDL锁视图:

执行SELECT * FROM INFORMATION_SCHEMA.METADATA_LOCK_INFO:

image.png

结合show processlist的结果,从元数据锁视图中可以明显看出:

l  session 4 pending在表t2metadata lock;

l  session 3持有表t2metadata lock,该MDL锁为事务级别,只要session 3的事务不提交,session 4便会一致阻塞;

所以,解决方法也很清晰,客户只需要在session 3中执行commitkill session 3,便可以让业务继续运行。

场景二 长时间持有MDL锁,导致全备失败

场景再现:

T

Session 2

Session 3

Session 4

Session 5

T1

lock tables t1 write;




T2

select *from t1;

insert into t2;


select *from t3

T3



Lock tables for backup;

(blocked)


T4


begin;

select *from t2;


begin;

insert into t3;

 

客户问题:

客户实例最近几次全备均失败,但是业务表现似乎正常,而且最近系统业务量不高,未出现明显问题;

 

问题排查过程:

Ø  MDL锁视图:

运维发现全备被阻塞后,首先show processlist,发现客户有多个活跃的客户session

image.png

全备是基于xtrabackup,在执行真正的备份之前需要执行lock tables for backup,但从show processlist中只能可以看到:

l  lock tables for backup时一直被某个MDL锁阻塞,全备超时失败;

l  用户的多个session确实业务量很小,都处于sleep状态;

于是,继续执行show open tables where in_use >=1

image.png

发现有个表t1始终处于in use状态,所以猜测是用户某个session持有了该表t1mdl锁,未释放,导致lock tables for backup等待超时。但是结合show processlist仍然无法确定是哪个session持有表t1mdl锁,想让全备执行成功,只能通知客户挨个断连session或者重启实例。

Ø  引入MDL锁视图:

执行SELECT * FROM INFORMATION_SCHEMA.METADATA_LOCK_INFO:

image.png

结合show processlist的结果,从元数据锁视图中可以明显看出:

l  session 4 pending在全局backup lock;

l  session 2持有全局的backup lock,该MDL锁类型为MDL_EXPLICITglobal级别;

所以,解决方法也很清晰了,客户只需要在session 2显式调用unlock tables释放锁或者kill session 2便可以让业务继续运行。

小结

从以上两个案例可以看出MDL锁视图的重要性,它可以让客户和一线运维人员清晰地查看数据库各session持有和等待的元数据锁信息,一目了然,从而找出数据库MDL锁等待的根因,准确地的进行下一步决策,有效降低对业务影响。


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。