![79afc48c50186140ad7e9f54500fbeb4.png](https://i-blog.csdnimg.cn/blog_migrate/d3ee8ea00605863f9d85191fd887139c.jpeg)
- DML语句通常按语句中提到**表的顺序获取**锁。
- DDL语句LOCK TABLES和其他类似的语句通过**按名称顺序获取**对显式命名的表的锁,试图减少并发DDL语句之间可能出现的死锁。
示例
rename table a 重命名为 b
# 创建测试表
root@yq [dblock]> create table a(id int);
Query OK, 0 rows affected (0.08 sec)
root@yq [dblock]> create table b(id int);
Query OK, 0 rows affected (0.03 sec)
root@yq [dblock]> create table c(id int);
Query OK, 0 rows affected (0.02 sec)
root@yq [dblock]> create table d(id int);
Query OK, 0 rows affected (0.04 sec)
root@yq [dblock]> show tables;
+------------------+
| Tables_in_dblock |
+------------------+
| a |
| b |
| c |
| d |
+------------------+
4 rows in set (0.00 sec)
a --> b 表切换
![6c499e705aa0a167e3ac76e638122b54.png](https://i-blog.csdnimg.cn/blog_migrate/190f21ecfa2b386f63cb10319618b5fc.png)
被阻塞的数据写入到了新切换过来的 a 表内
root@yq [dblock]> select * from a;
+------+
| id |
+------+
| 1 |
+------+
1 row in set (0.00 sec)
root@yq [dblock]> select * from a_old;
Empty set (0.00 sec)
1. 按顺序对a和b上请求获取X锁.
2. 请求被阻塞等待a表上的X锁
3. rename时候按照名称顺序也是等待a表上的X锁
4. unlock释放锁,由于session3上的锁的优先级高,因此先释放执行了rename操作,然后执行了insert操作。
d --> c 表切换
![e0fc4e87338b8c0632d24b73c4f40c15.png](https://i-blog.csdnimg.cn/blog_migrate/456eadfdb1352c3d706bcef8a4cd5d82.png)
被阻塞的数据写入到了原来的 d_old 表内
root@yq [dblock]> select * from d;
Empty set (0.00 sec)
root@yq [dblock]> select * from d_old;
+------+
| id |
+------+
| 1 |
+------+
1 row in set (0.00 sec)
1. 按顺序对c和d上请求获取X锁.
2. 请求被阻塞等待d表上的X锁
3. rename时候按照名称顺序等待c表上的X锁
4. unlock释放锁,session2 是唯一对c表上持有锁,而session3的重命名操作仍然需等待session2上的X锁释放,因此session2会先执行完成后在执行session3。
同样的rename操作,数据一个写在新且的表,一个写在原表中了,惊不惊喜,意不意外?~
结论
对于元数据加锁,会根据表名称的顺序来进行加,可以调整表名以影响锁获取的顺序。
参考: https:// dev.mysql.com/doc/refma n/8.0/en/metadata-locking.html