快速定位MySQL的MDL锁等待

演示环境MySQL版本mysql5.7.22

查看是否持有MDL锁等待:

特别说明:

通过sys.schema_table_lock_waits视图 可以查看当前连接线程的MDL锁等待信息,显示哪些会话被MDL锁阻塞,是谁阻塞了这些会话,数据来源 performance_schema下的threads,metadata_locks,events_statements_current表,此视图是在MySQL5.7.9中新增的



使用视图sys.schema_table_lock_waits 查看MDL锁等待,首先需要开启与MDL锁等待事件相关的instruments:


'tidb03' root@localhost 17:21:58 (none)>update performance_schema.setup_instruments set ENABLED='no',timed='no' where name like 'wait/lock/metadata/sql/mdl';

Query OK, 1 row affected (0.00 sec)

Rows matched: 1 Changed: 1 Warnings: 0

'tidb03' root@localhost 17:14:11 (none)>call sys.ps_setup_enable_instrument('wait/lock/metadata/sql/mdl');

+-----------------------+

| summary |

+-----------------------+

| Enabled 1 instruments |

+-----------------------+

1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.

显示的1代表 MDL锁等待事件相关的instruments未开启

显示的0代表 MDL锁等待事件相关的instruments开启:

update performance_schema.setup_instruments set ENABLED='yes',timed='yes' where name like 'wait/lock/metadata/sql/mdl';

'tidb03' root@localhost 17:22:51 (none)>select * from performance_schema.setup_instruments where name like 'wait/lock/metadata/sql/mdl';

+----------------------------+---------+-------+

| NAME | ENABLED | TIMED |

+----------------------------+---------+-------+

| wait/lock/metadata/sql/mdl | YES | YES |

+----------------------------+---------+-------+

'tidb03' root@localhost 16:53:54 (none)>call sys.ps_setup_enable_instrument('wait/lock/metadata/sql/mdl');

+-----------------------+

| summary |

+-----------------------+

| Enabled 0 instruments |

+-----------------------+

1 row in set (0.00 sec)
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.



会话一:发起一个update更新记录的事务


'tidb03' root@localhost 16:46:37 test001>select * from test001;

+----+----------+----------+---------------------+

| id | username | password | create_time |

+----+----------+----------+---------------------+

| 1 | 大米 | abc123 | 2021-09-19 13:31:07 |

+----+----------+----------+---------------------+

1 row in set (0.00 sec)



'tidb03' root@localhost 16:46:40 test001>

'tidb03' root@localhost 16:46:40 test001>

'tidb03' root@localhost 16:46:40 test001>

'tidb03' root@localhost 16:46:41 test001>begin;

Query OK, 0 rows affected (0.00 sec)

'tidb03' root@localhost 16:46:47 test001>update test001 set username='小白' where id=1;

Query OK, 1 row affected (0.00 sec)

Rows matched: 1 Changed: 1 Warnings: 0
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.


会话二:发起aler table 操作 

'tidb03' root@localhost 16:47:22 test001>alter table test001 add index idx_username(username);



会话三: 查看视图sys.schema_table_lock_waits定位MDL锁等待

'tidb03' root@localhost 16:51:08 (none)>select * from sys.schema_table_lock_waits\G

*************************** 1. row ***************************

object_schema: test001 #发生MDL锁等待的schema名称

object_name: test001 #正在等待MDL锁的表名称

waiting_thread_id: 206617 #正在等待MDL锁的线程id

waiting_pid: 206592 #正在等待MDL锁的 processlist id

waiting_account: root@localhost #正在等待MDL锁与线程相关的账户名称

waiting_lock_type: EXCLUSIVE #被阻塞的线程正在等待的MDL锁类型

waiting_lock_duration: TRANSACTION #该字段来自元数据锁子系统中的锁定事件,值为:STATEMENT,TRANSACTION,EXPLICIT;STATEMENT和TRANSACTION表示语句或者事务结束时会释放的锁。

XPLICIT表示在语句和事务结束时会被保留,需要显式释放的锁:例如flush table with read lock 获取的全局的锁

waiting_query: alter table test001 add index idx_username(username) ##正在等待MDL锁线程对应的sql

waiting_query_secs: 206 ##正在等待MDL锁的语句已经等待了多长时间

waiting_query_rows_affected: 0 ##受等待MDL锁语句影响的数据行数,此字段来自performance_schema.events_statements_current,此表记录的是语句事件,

如果语句是多表连结查询的话,则整体sql语句可能已经执行了一份部分的DML语句,所以即使该sql被当前其他线程阻塞了,被阻塞线程的这个字段的数值也可能是大于0的

waiting_query_rows_examined: 0 ## 原理同上

blocking_thread_id: 206617 ##持有MDL锁的线程id

blocking_pid: 206592 ##持有MDL锁的processlist id

blocking_account: root@localhost

blocking_lock_type: SHARED_UPGRADABLE ##持有MDL锁的锁类型

blocking_lock_duration: TRANSACTION ##和字段waiting_lock_duration解释相同

sql_kill_blocking_query: KILL QUERY 206592 ##生成的KILL 持有MDL锁的查询语句

sql_kill_blocking_connection: KILL 206592 ##生成的KILL 持有MDL锁的对应的会话语句

*************************** 2. row ***************************

object_schema: test001

object_name: test001

waiting_thread_id: 206617

waiting_pid: 206592

waiting_account: root@localhost

waiting_lock_type: EXCLUSIVE

waiting_lock_duration: TRANSACTION

waiting_query: alter table test001 add index idx_username(username)

waiting_query_secs: 206

waiting_query_rows_affected: 0

waiting_query_rows_examined: 0

blocking_thread_id: 206628

blocking_pid: 206603

blocking_account: root@localhost

blocking_lock_type: SHARED_WRITE

blocking_lock_duration: TRANSACTION

sql_kill_blocking_query: KILL QUERY 206603

sql_kill_blocking_connection: KILL 206603

2 rows in set (0.01 sec)
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
posted @ 2021-09-20 18:12  勤奋的蓝猫  阅读(2)  评论(0编辑  收藏  举报  来源