更新时间:2025-05-14 gmt 08:00

mdl锁视图-j9九游会登录

mdl锁视图简介

社区版mysql如果不打开performance_schema开关,则无法获取表元数据锁(mdl)的详细信息,但通常情况下performance_schema默认关闭,当用户遇到类似“waiting for metadata lock”的问题而阻塞dml或ddl后,由于无法确定各个会话之间的关联关系,只能重启实例,增加了解决问题的成本,对业务产生了较大影响。

在业务场景较复杂的情况下,一旦涉及对数据库元数据的互斥操作(如ddl、lock table等),会频繁发生操作的会话被其他会话阻塞的问题,给用户带来很大的困扰。

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

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的会话,便可以让业务继续运行。

相关文档

网站地图