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 锁等待的根因,准确地进行下一步决策,有效降低对业务的影响。
本文转载自华为云社区公众号。
原文链接:https://mp.weixin.qq.com/s/sxcRvNtPv-EcSDOeJub5qA
评论