MySQL的MDL (元数据锁) Waiting for table metadata lock

问题

对表t1进行查询操作一直显示sending data 中,导致后续对t1表的所有操作select、insert、update、delete全部阻塞!!

MDL:Metadata Locking,元数据锁

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 and stored programs (procedures, functions, triggers, and scheduled events).

Metadata locking does involve some overhead, which increases as query volume increases. Metadata contention increases the more that multiple queries attempt to access the same objects.

为了在并发环境下维护表元数据的数据一致性,在表上有活动事务(显式或隐式)的时候,不可以对元数据进行写入操作。因此从MySQL5.5版本开始引入了MDL锁(metadata lock),来保护表的元数据信息,用于解决或者保证DDL操作与DML操作之间的一致性。
对于引入MDL,其主要解决了2个问题,一个是事务隔离问题,比如在可重复读隔离级别下,会话A在2次查询期间,会话B对表结构做了修改,两次查询结果就会不一致,无法满足可重复读的要求;另外一个是数据复制的问题,比如会话A执行了多条更新语句期间,另外一个会话B做了表结构变更并且先提交,就会导致slave在重做时,先重做alter,再重做update时就会出现复制错误的现象。

MDL是在server层实现的!

在这里插入图片描述

MDL类型
在这里插入图片描述

在这里插入图片描述

MDL常见的场景:

场景一:长事务运行,阻塞DDL,继而阻塞所有同表的后续操作

通过show processlist可以看到TableA上有正在进行的操作(包括读),此时alter table语句无法获取到metadata 独占锁,会进行等待。

场景二:未提交事务,阻塞DDL,继而阻塞所有同表的后续操作

通过show processlist看不到TableA上有任何操作,但实际上存在有未提交的事务,可以在 information_schema.innodb_trx中查看到。在事务没有完成之前,TableA上的锁不会释放,alter table同样获取不到metadata的独占锁。
场景三:特殊场景

TableA存在一个查询失败的语句,比如查询不存在的列,语句失败返回,但是事务没有提交,但是在information_schema.innodb_trx 看不到,此时alter仍然会被堵住。

MDL应急处理:

使用show full processlist; 查看事务的id,进而kill 掉导致阻塞的事务。

猜你喜欢

转载自blog.csdn.net/shunnianlv/article/details/105998951