Mysql 死锁过程及案例详解之元数据锁MetaData Lock

Posted ShenLiang2025

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mysql 死锁过程及案例详解之元数据锁MetaData Lock相关的知识,希望对你有一定的参考价值。

mysql数据锁MetaData Lock

元数据锁MetaData Lock

元数据锁MetaData Locks的主要作用是在执行查询或者发起事务时元数据结构受到保护,即不被修改。

MetaData Lock是表级锁。

MetaData Lock是排他锁,当该锁存在时不能有其它的连接对表的模式进行修改。

关于元数据锁的最大问题是空闲事务(因网络断开或者程序Bug而导致的COMMIT/ROLLBACK语句没有传给数据库,也没有释放线程而导致线上事务锁定等待严重、连接数暴涨的情况)会阻止DDL语句的执行。

示意案例

--Step1 会话1里查看连接ID
SELECT CONNECTION_ID();
/*
CONNECTION_ID()
8
*/
START TRANSACTION;
SELECT *,SLEEP(15) FROM emp WHERE empno=7566;

--Step2 会话2里查看连接ID
SELECT CONNECTION_ID();
/*
CONNECTION_ID()
9
*/

OPTIMIZE TABLE emp;

--Step3 会话3里查看查看连接ID
SELECT thd_id, conn_id, state,
current_statement,
last_statement
FROM sys.session
WHERE conn_id IN (8, 9)

thd_id	conn_id	state	current_statement	last_statement
49	9	Waiting for table metadata lock	OPTIMIZE TABLE emp	
48	8			SELECT *,SLEEP(60) FROM emp WHERE empno=7566


通过这个示例我们可以看到有个会话1在执行有个持续的事务,而在第二个会话里执行了语句 OPTIMIZE TABLE emp(OPTIMIZE TABLE语句本身不会改变表的结构,但是会触发metadata lock),知道会话1里的事务提交或者回滚后会话2才能正常执行,即metalock锁释放。

我们也可以通过系统表(视图)来查看当前metadata lock的情况。


--会话3里执行
Connection 3> SELECT *
FROM performance_schema.metadata_locks
WHERE OBJECT_NAME = 'emp'

mysql> SELECT * FROM performance_schema.metadata_locks WHERE OBJECT_NAME = 'emp' \\G
*************************** 1. row ***************************
          OBJECT_TYPE: TABLE
        OBJECT_SCHEMA: ShenLiang2025
          OBJECT_NAME: emp
          COLUMN_NAME: NULL
OBJECT_INSTANCE_BEGIN: 139887555287408
            LOCK_TYPE: SHARED_READ
        LOCK_DURATION: TRANSACTION
          LOCK_STATUS: GRANTED
               SOURCE: sql_parse.cc:5801
      OWNER_THREAD_ID: 51
       OWNER_EVENT_ID: 80
*************************** 2. row ***************************
          OBJECT_TYPE: TABLE
        OBJECT_SCHEMA: ShenLiang2025
          OBJECT_NAME: emp
          COLUMN_NAME: NULL
OBJECT_INSTANCE_BEGIN: 139887489260736
            LOCK_TYPE: SHARED_NO_READ_WRITE
        LOCK_DURATION: TRANSACTION
          LOCK_STATUS: PENDING
               SOURCE: sql_parse.cc:5801
      OWNER_THREAD_ID: 52
       OWNER_EVENT_ID: 13
2 rows in set (0.00 sec)

这里可以看到进程ID号是51由于是一个未完成的事务,所以获得一个共享的读锁。
而进程ID是52的会话则因为执行了DDL语句在等待锁释放,即状态是PENDING。

以上是关于Mysql 死锁过程及案例详解之元数据锁MetaData Lock的主要内容,如果未能解决你的问题,请参考以下文章

Mysql 死锁过程及案例详解之用户自定义锁

Mysql 死锁过程及案例详解之用户自定义锁

Mysql 死锁过程及案例详解之清空缓存锁Flush Lock

Mysql 死锁过程及案例详解之清空缓存锁Flush Locks

Mysql 死锁过程及案例详解之记录锁与间隔锁Record Lock Gap Lock

Mysql 死锁过程及案例详解之插入意向锁与自增锁备份锁日志锁Insert Intention Lock Auto-increment Lock Backup Lock Log Lock