快速应对metadata lock问题

                                                    1

最近遇到一次metadata lock导致大量线程卡住的问题,比较有代表性,撰文一篇,希望对广大DBA们有帮助。

同事反馈说在使用pt-online-schema-change添加索引的时候,一直卡住,而且会卡住很久。

登录服务器,使用show full processlist命令查看线程状态,发现大量的Waiting for table metadata lock,如下图:

找到等待时间最长Waiting for table metadata lock的SQL,正是同事添加索引的时候创建触发器的SQL,如下图:

初步确定原因是创建触发器的时候,有某个事务持有metadata lock没有释放,导致创建触发器的SQL被阻塞,进而导致后面关于t_log_sp_detail_10的所有操作都被阻塞。

解决办法,终止添加索引的操作,kill掉创建触发器的线程,业务恢复。


                                                    2

这里面引申出2个问题:

1、是什么SQL持有metadata lock那么长的时间一直不释放?

2、为什么metadata lock那么长的时间都不超时?

下面就来寻根问底:

我们的环境是5.7,在MySQL 5.7中,可以通过查看performance_schema.metadata_locks来查看对应metadata lock的情况,开启方式如下:


UPDATE performance_schema.setup_consumers SET ENABLED = 'YES' WHERE NAME ='global_instrumentation';


UPDATE performance_schema.setup_instruments SET ENABLED = 'YES' WHERE NAME ='wait/lock/metadata/sql/mdl';


不过在performance_schema.metadata_locks表中并没有记录对应的线程ID,需要结合performance_schema.INNODB_TRX来进一步分析。

但是,那台机器关闭了performance_schema,如果要启用的话必须重启实例,因此只能使用笨一点的办法。

只要抓取对应的信息就能快速定位,这些信息包括:

(1)、开启general日志(短暂开启)

(2)、抓取show full processlist的信息(每隔1秒)

(3)、抓取performance_schema.INNODB_TRX的信息(每隔1秒)

通知同事,继续使用pt添加索引,重现问题。

问题重现后,查看抓取到的performance_schema.INNODB_TRX信息,找到对应事件正在进行的事务,截图如下:

查看general日志对应线程做了什么事情:

查看抓取到proocesslist信息,发现这个线程是sleep的状态,问题很明显是这个线程没有提交导致。

和业务沟通后,kill掉该线程,索引正常添加。

第1个问题答案是select线程没有提交导致。


再来看第2个问题

之所以等待那么久都没有超时,是因为metadata lock不是InnoDB引擎层的锁,而是server层的锁,控制锁超时的参数不一样,如下:

上面的截图中innodb_lock_wait_timeout是控制InnoDB引擎层的锁超时,而lock_wait_timeout是控制server层的锁超时。

而上图中,lock_wait_timeout设置得很大,可以调小。


                                                    3

回答完上面的2个问题,我们再来深入一点了解一下metadata lock这个东东。主要从3个方面来看:

一、为什么要引入metadata lock

    为了在并发环境下维护表元数据的数据一致性,在表上有活动事务(显式或隐式)的时候,不可以对元数据进行写入操作。因此从MySQL5.5版本开始引入了MDL锁(metadata lock),来保护表的元数据信息,用于解决或者保证DDL操作与DML操作之间的一致性。

    上面的描述可能不是特别好理解,来举一个之前姜老师说过的例子,这个例子就能很形象地说明为什么要引入metadata lock。看如下两个session

上面的例子中,如果没有metadata lock的保护,会导致SESSION 2顺利执行,SESSION 1出错。

在5.5.3版本加入metadata lock以后,由于SESSION 1先查询了TABLE1,持有TABLE1的metadata lock,会导致SESSION 2等待,直到SESSION 1提交。

正因为如此,MySQL在5.5.3版本后引入了Metadata lock锁,事务释放后才会释放Metadata lock,因此,在事务完成之前,DDL是无法执行的。

有兴趣的还可以看看这个典型的bug。

https://bugs.mysql.com/bug.php?id=989

二、什么场景下会引起metadata lock

有如下几种场景会引起metadata lock锁等待问题

1、有长时间运行的DML语句

      这种情况会导致metadata lock等待,在工作中如果要对某个表进行DDL操作之前,需要先用show processlist看看是否有长时间运行的SQL,防止出现线上故障。

2、有未提交的事务

      这个就是我们开篇遇到的问题,不管是select还是update,如果没有提交都会造成metadata lock等待。

3、在执行期间失败的语句,不会立即释放metadata lock

    官网是这么说的:

If the server acquires metadata locks for a statement that is syntactically valid but fails during execution, it does not release the locks early. Lock release is still deferred to the end of the transaction because the failed statement is written to the binary log and the locks protect log consistency.

    举个例子就很容易理解了,比如我开启一个事务,查询一个不存在的事务,索然语句执行失败,但是持有的metadata lock并没有释放:

session1执行如下操作:

session 2执行添加字段的DDL,session2就一直在等待中,直到session1提交

三、如何快速解决metadata lock引发的锁等待问题

从上面原理和场景中,我们可以看到基本就两种情况。

一种是有长时间运行的DML语句的时候,这种情况要么kill掉DDL语句,要么就kill掉长时间运行的DML。

另外一种情况是未提交的事务(正常的语句和失败的语句),这种情况要解决稍微复杂一点,需要找到对应没有提交的线程进行kill,或者kill掉DDL语句。最快速的解决办法就是将所有sleep的线程都杀掉。

备注:将所有sleep的线程都杀掉这个操作会导致没有提交的事务回滚,是有风险的,请根据业务场景进行操作。

延展阅读:https://www.cnblogs.com/zengkefu/p/5690385.html 【姜老师的文章】

四、参考资料:

https://dev.mysql.com/doc/refman/5.7/en/metadata-locking.html

https://www.cnblogs.com/zengkefu/p/5690385.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,864评论 6 494
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,175评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,401评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,170评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,276评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,364评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,401评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,179评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,604评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,902评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,070评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,751评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,380评论 3 319
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,077评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,312评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,924评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,957评论 2 351

推荐阅读更多精彩内容