关于数据库:有了MDL锁视图业务死锁从此一目了然

53次阅读

共计 2804 个字符,预计需要花费 8 分钟才能阅读完成。

摘要: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 锁视图的最佳时机。

正文完
 0