表级锁的种类
MySQL里面表级别的锁有两种,一种是表锁,另一种是元数据锁(MDL, meta data lock)。
1. 表锁
- 语法
lock tables TABLE_NAME read/write;
- 释放锁的时机
- 使用显式命令 unlock tables
- 当加锁的客户端与服务器端断开连接时
- 需要注意的是
lock tables
除了限制其他线程读写表数据之外,还会限制本线程对表的访问,例如执行lock tables T1 read, T2 write;
那么其他线程写T1和读写T2的请求就被阻塞了。但是也同时限制了当前线程只能读T1和读写T2,也不能操作其他表。
2. MDL锁
MDL锁不需要显式添加,在访问一个表的时候会自动给这个表加上MDL锁,以保证查询出的内容与表结构同步。
MDL锁有时候会带来一些麻烦。我们知道,为一个表加字段或者修改字段或者建立索引时会遍历全表,因此对一个大表操作时要格外小心。不过如果对MDL锁理解不到位,对一个小表加字段时也可能会让整个数据库崩溃。例如下面的操作:
图1 加字段造成阻塞
如图一所示,session1开启事务执行查询语句,这时会加上MDL读锁。session2也要加读锁,所以可以正常执行。session3因为要加字段所以需要请求MDL写锁,这时候就会被阻塞,直到session1和session2执行完成。不过session3同样也会阻塞掉所有后面的session对于该表的读写请求,如果阻塞时间太长的话,session4的客户端会重新发送请求重试,如果这样的请求和重试太多的话,很快就会耗尽服务器端的线程,造成数据库崩溃。
网友评论