RDS for Mysql的MDL锁视图

举报
Hans 发表于 2024/04/26 23:52:57 2024/04/26
【摘要】 1、MDL锁概念       MDL全称为metadata lock,即元数据锁。官方对MDL锁的定义如下:MySQL uses metadata locking to manage concurrent access to database objects and to ensure data consistency. Metadata locking applies not just t...

1、MDL锁概念

       MDL全称为metadata lock,即元数据锁。官方对MDL锁的定义如下:

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锁主要作用是维护表元数据(包括 table,schema, function, procedure, trigger, event等)的数据一致性,在表上有活动事务(显式或隐式)的时候,不可以对元数据进行写入操作。主要解决了2个问题,一个是事务隔离问题,比如在可重复隔离级别下,会话A在2次查询期间,会话B对表结构做了修改,两次查询结果就会不一致,无法满足可重复读的要求;另外一个是数据复制的问题,比如会话A执行了多条更新语句期间,另外一个会话B做了表结构变更并且先提交,就会导致slave在重做时,先重做alter,再重做update时就会出现复制错误的现象。

2、社区版MDL锁的限制

        MDL锁通常发生在DDL操作挂起的时候,原因是有未提交的事务对该表进行DML操作。而MySQL的会话那么多,不知道哪个会话的操作没有及时提交影响了DDL。社区版MySQL如果不打开performance_schema开关,则无法获取表元数据锁(MDL)的详细信息,通常我们排查这类问题,往往需要从information_schema.innodb_trx表中查询当前在执行的事务,但当SQL已经执行过了,没有commit,这个时候这个表中是看不到SQL的。当用户遇到类似“Waiting for metadata lock”的问题而阻塞DML或DDL后,由于无法确定各个会话之间的关联关系,只能重启实例,增加了解决问题的成本,对业务产生了较大影响。在业务场景较复杂的情况下,一旦涉及对数据库元数据的互斥操作(如DDL、LOCK TABLE等),会频繁发生操作的会话被其他会话阻塞的问题,给用户带来很大的困扰。

3、华为云RDS For Mysql的MDL锁视图

      华为云RDS for MySQL推出了MDL锁视图特性,可以查看数据库各会话持有和等待的元数据锁信息,用户可以有效进行系统诊断,优化自身业务,有效降低对业务影响。

    MDL锁视图以系统表的形式呈现,该表位于“information_schema”下,表名称是“metadata_lock_info”。表结构如下所示。

desc information_schema.metadata_lock_info;
+---------------+-----------------------+---------+------+----------+--------|
| Field         | Type                  | Null    |Key   |Default   |  Extra |
+---------------+-----------------------+---------+------+----------+--------|
| THREAD_ID     | bigint(20) unsigned   | NO      |      |   0      |        |
| LOCK_STATUS   | varchar(24)           | NO      |      |          |        |
| LOCK_MODE     | varchar(24)           | YES     |      |  NULL    |        |
| LOCK_TYPE     | varchar(30)           | YES     |      |  NULL    |        |
| LOCK_DURATION | varchar(30)           | YES     |      |  NULL    |        |
| TABLE_SCHEMA  | varchar(64)           | YES     |      |  NULL    |        |
| TABLE_NAME    | varchar(64)           | YES     |      |  NULL    |        |
+---------------+-----------------------+---------+------+----------+--------|

表1 metadata_lock_info字段

序号

字段名

字段定义

字段说明

0

THREAD_ID

bigint(20) unsigned

会话ID。

1

LOCK_STATUS

varchar(24)

MDL锁的两种状态。

  • PENDING:表示会话正在等待该MDL锁。
  • GRANTED:表示会话已获得该MDL锁。

2

LOCK_MODE

varchar(24)

加锁的模式,如MDL_SHARED 、MDL_EXCLUSIVE 、MDL_SHARED_READ、MDL_SHARED_WRITE等。

3

LOCK_TYPE

varchar(30)

MDL锁的类型,如Table metadata lock、Schema metadata lock、Global read lock、Tablespace lock等。

4

LOCK_DURATION

varchar(30)

MDL锁范围,取值如下:

  • MDL_STATEMENT:表示语句级别。
  • MDL_TRANSACTION:表示事务级别。
  • MDL_EXPLICIT:表示GLOBAL级别。

5

TABLE_SCHEMA

varchar(64)

数据库名,对于部分GLOBAL级别的MDL锁,该值为空。

6

TABLE_NAME

varchar(64)

表名,对于部分GLOBAL级别的MDL锁,该值为空。

MDL锁视图使用示例

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

表2 MDL锁视图示例

表名

会话

session2

session3

session4

session5

t1

begin;

select * from t1;

-

-

-

t2

-

begin;

select * from t2;

-

-

t3

-

-

truncate table t2;

(blocked)

-

t4

-

-

-

begin;

select * from t2;

(blocked)

MDL锁视图案例分析

问题描述

用户发现对表t2执行truncate操作一直被阻塞后,业务流程中对表t2执行查询操作也全部被阻塞。

排查分析

  • 无MDL锁视图

    当发现DDL语句被阻塞后,执行show processlist查看线程信息,结果如下所示。

    show processlist;
    +------+--------+--------------+--------+-----------+----------+-----------------------------------|-------------------------|
    | Id   | User   |  Host        |  db    |  Command  |   Time   |   State                           |Info                     |
    +---------------+-----------------------+-----------+----------+-----------------------------------+-------------------------|
    | 2    | root   |  localhost   |  test  |  Sleep    |   73     |                                   | Null                    |
    | 3    | root   |  localhost   |  test  |  Sleep    |   63     |                                   | Null                    |
    | 4    | root   |  localhost   |  Null  |  Query    |   35     | Waiting for table metadata lock   | truncate table test.t2  |
    | 5    | root   |  localhost   |  test  |  Query    |   17     | Waiting for table metadata lock   | select * from test.t2   |
    | 6    | root   |  localhost   |  test  |  Query    |    0     | starting                          | show processlist        |
    +------+--------+--------------+--------+-----------+----------+-----------------------------------|-------------------------|

    上述线程列表信息显示:

    • ID=4的会话执行truncate操作时被其他会话持有的table metadata lock阻塞。
    • ID=5的会话执行查询操作时同样被阻塞。
    • 无法确定哪个会话阻塞了ID=4的会话和ID=5的会话。

    此时,如果随机KILL其他会话会给线上业务带来很大风险,因此只能等待其他会话释放该MDL锁。

  • 使用MDL锁视图

    执行select * from information_schema.metadata_lock_info查看元数据锁信息,结果如下所示。

    select * from information_schema.metadata_lock_info;
    +-------------+-------------+--------------------------+----------------------+-------------------+----------------+----------------+
    | THREAD_ID   | LOCK_STATUS |  LOCK_MODE               | LOCK_TYPE            |  LOCK_DURATION    |  TABLE_SCHEMA  |   TABLE_NAME   |
    +-------------+-------------+--------------------------+----------------------+-------------------+----------------+----------------+
    | 2           | GRANTED     |  MDL_SHARED_READ         | Table metadata lock  |  MDL_TRANSACTION  |  test          |   t1           |
    | 3           | GRANTED     |  MDL_SHARED_READ         | Table metadata lock  |  MDL_TRANSACTION  |  test          |   t2           |
    | 4           | GRANTED     |  MDL_INTENTION_EXCLUSIVE | Global read lock     |  MDL_STATEMENT    |                |                |
    | 4           | GRANTED     |  MDL_INTENTION_EXCLUSIVE | Schema metadata lock |  MDL_TRANSACTION  |  test          |                |
    | 4           | PENDING     |  MDL_EXCLUSIVE           | Table metadata lock  |                   |  test          |   t2           |
    | 5           | PENDING     |  MDL_SHARED_READ         | Table metadata lock  |                   |  test          |   t2           |
    +-------------+-------------+--------------------------+----------------------+-------------------+----------------+----------------+

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

    上述线程信息和元数据锁视图信息显示:

    • THREAD_ID=4的会话正在等待表t2的metadata lock。
    • THREAD_ID=3的会话持有表t2的metadata lock,该MDL锁为事务级别,因此只要THREAD_ID=3的会话的事务不提交,THREAD_ID=4的会话将会一直阻塞。

    因此,用户只需在THREAD_ID=3的会话中执行命令commit或终止THREAD_ID=3的会话,便可以让业务继续运行。

    MDL锁视图的优点:可以让客户和一线运维人员清晰地查看数据库各session持有和等待的元数据锁信息,从而找出数据库MDL锁等待的根因,准确地进行下一步决策,有效降低对业务的影响。
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

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

全部回复

上滑加载中

设置昵称

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

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

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