mysql锁系列之全局锁

版权声明:本文章为博主原创文章,未经博主允许不得转载,如有问题,欢迎留言交流指正 https://blog.csdn.net/finalkof1983/article/details/88144529

基础材料:

centos7.5  mysql 5.7.24


mysql的锁按级别可以分为三大类:全局锁、表级锁、行级锁,本篇主要对全局锁进行说明。

全局锁就对整个数据库实例加锁,加锁后整个实例就处于只读状态,后续的MDL的写语句,DDL语句,已经更新操作的事务提交语句都将被阻塞。其典型的使用场景是做全库的逻辑备份,对所有的表进行锁定,从而获取一致性视图,保证数据的完整性。

加全局锁的命令为:

mysql> flush tables with read lock;

释放全局锁的命令为:

1、mysql>unlock tables;

2、断开加锁session的连接


说到全局锁用于备份这个事情,还是很危险的。因为如果在主库上加全局锁,则整个数据库将不能写入,备份期间影响业务运行,如果在从库上加全局锁,则会导致不能执行主库同步过来的操作,造成主从延迟。

对于innodb这种支持事务的引擎,使用mysqldump备份时可以使用--single-transaction参数,利用mvcc提供一致性视图,而不使用全局锁,不会影响业务的正常运行。而对于有MyISAM这种不支持事务的表,就只能通过全局锁获得一致性视图,对应的mysqldump参数为--lock-all-tables。


全局锁的实现还是依赖于元数据锁的,为了查看mysql全局锁的加锁行为,初始化实验环境如下,各session按序执行:

session129 session126 session128 session131
begin; alter table testok add  x int; flush tables with read lock; alter table testok add  y int;
select * from testok;      

 此时查看metadata_locks状态如下:

session129取得testok表的共享锁

session126在全局和数据库层面加了意向排他锁,在表testok上加了共享可升级锁,在表上加排他锁时pending,此时在等待session129的共享锁释放。

session128在全局加共享锁时pending,此时在等待session126的全局意向排他锁释放。

session131在加全局意向排他锁时pending,因为元数据锁操作队列中,在它前面的session128,也需要在全局层加锁,且与自身锁类型互斥,所以在全局层就被阻塞了,无法像session126那样继续向下层加锁,这样的设计应该是防止session128这种操作<饿死>。

此时在session129处执行commit,再观察metadata_locks状态如下:

 session129释放共享锁,session126拿到排他锁执行完成并提交,释放排他锁,此时由于全局层共享锁优先级高于意向排他锁且互斥,所以session128获得全局共享锁,而session131继续pending,等待session128的全局共享锁。

猜你喜欢

转载自blog.csdn.net/finalkof1983/article/details/88144529