什么是MySQL的字典锁?
MySQL的字典锁,也称为元数据锁(MDL,MetaData Lock),是一种为了保护数据库对象的元数据而设计的锁机制。
在 MySQL 5.5.3 之前有个 bug#989 ,大概得操作流程如下:
事务A
BEGIN;
INSERT INTO t ... ;
COMMIT;
事务B
DROP TABLE t;
最终的在 binlog 中记录的是先删除表在插入数据,这样备份库在同步数据时就被中断了。为了解决这个问题,MySQL5.5.3 版本引入了 MDL 锁保护表的元数据信息,用于解决或者保证DDL操作与DML操作之间的一致性。
MDL是表级锁,是在server层加的,适用于所有存储引擎。所有的dml操作都会在表上加一个MDL读锁;所有的ddl操作都会在表上加一个MDL写锁。
读锁和写锁的阻塞关系如下:
- 读锁和写锁之间相互阻塞,即同一个表上的dml和ddl之间互相阻塞。
- 写锁和写锁之间互相阻塞,即两个session不能对表同时做表定义变更,需要串行操作。
- 读锁和读锁之间不会产生阻塞。也就是增删改查不会因为MDL 锁产生阻塞,可以并发执行,日常工作中大家看到的dml之间的锁等待是innodb行锁引起的,和MDL 锁无关。
熟悉innodb行锁的同学这里可能有点困惑,因为行锁分类和MDL锁很类似,也主要分为读锁和写锁,或者叫共享锁和排他锁,读写锁之间阻塞关系也一致。二者最重要的区别一个是表锁,一个是行锁,且行锁中的读写操作对应在 MDL 锁中都属于读锁。