一个线下库环境,开发人员不提交DML和查询事务,导致drop database时,遭遇表的metadata lock(MDL)等待,而不是SCHEMA上。
即会看到 “Waiting for table metadata lock”,而不是”Waiting for schema metadata lock”。这是为什么呢?
经过源码分析,原因如下。
我们知道:
select 语句在操作时,需要对表对象持有MDL_SHARED_READ锁。
而DML语句在操作时,需要对表对象持有MDL_SHARED_WRITE锁。但都不需要SCHEMA级别metadata lock锁。
另外drop database 时,需要依次获取以下MDL锁:
1) MDL_INTENSION_EXCLUSIVE(GLOBAL),STATEMENT 级别
2) MDL_EXCLUSIVE(SCHEMA),TRANSACTION级别
3) MDL_EXCLUSIVE (TABLE),TRANSACTION级别。在此database下的每个对象,需要MDL_EXCLUSIVE锁。
那么原因就非常明显了:
这是因为查询或者DML一张表时,只会获取这个表的MDL_SHARED_READ或者MDL_SHARED_WRITE锁;
而drop database 时,会按以上流程获取相关锁,因此只在第三步有冲突,前面两步不会有冲突。
示例如下:
1. 起查询事务
2. 删除数据库,此时当前会话hang住。
3. Show processlist结果,看到有”Waiting for table metadata lock”。