MySQL全局锁
悲观者从机会中看到困难。乐观者从困难中看到机会。
——温斯顿·丘吉尔
全局锁是怎么用的?
要使用全局锁,则要执行这条命令:
flush tables with read lock
执行后,整个数据库就处于只读状态了。这时其他线程执行一下操作,都会被阻塞:
- 对数据的增删改操作,比如insert、delete、update等语句;
- 对表结构的更改操作,比如alter table、drop table等语句;
如果要释放全局锁,则要执行这条命令:
unlock tables
当然,当会话断开了,全局锁会被自动释放。
全局锁应用场景
全局锁主要应用于做全库逻辑备份,这样在备份数据库期间,不会因为数据或表结构的更新,而出现备份文件的数据与预期的不一样。
举个例子大家就知道了,
在全库逻辑备份期间,假设不加全局锁的场景,看看会出现什么意外的情况。
如果在全库逻辑备份期间,有用户购买了一件商品,一般购买商品的业务逻辑是会涉及到多张数据库表的更新,比如在用户表更新该用户的余额,然后在商品表更新被购买的商品的库存
那么,有可能出现这样的顺序:
1.先备份了用户表的数据;
2.然后有用户发起了购买商品的操作;
3.接着再备份商品表的数据。
也就是在备份用户表和商品表之间,有用户购买了商品
这种情况下,备份的结果是用户表中该用户的余额并没有扣除,反而商品表中该商品的库存被减少了,如果后面用这个备份文件恢复数据库数据的话,用户钱没少,而库存少了,等于用户白了一件商品。
所以,在全库逻辑备份期间,加上全局锁,就不会出现上面这种情况了。
加全局锁又会带来什么缺点呢?
加上全局锁,意味着整个数据库都是只读状态。
那么如果数据库里有很多数据,备份就会花费很多的时间,关键是备份期间,业务只能读数据,而不能更新数据,这样会造成业务停滞。
既然备份数据库数据的时候,使用全局锁会影响业务,那有什么其它方式可以避免
有的,如果数据库的引擎支持的事务支持可重复读的隔离级别,那么在备份数据库之前先开启事务,会先创建 Read View,然后整个事务执行期间都在用这个 Read View,而且由于 MVCC 的支持,备份期间业务依然可以对数据进行更新操作
因为在可重复读的隔离级别下,即使其他事务更新了表的数据,也不会影响备份数据库时的 Read View.这就是事务四大特性中的隔离性,这样备份期间备份的数据一直是在开启事务时的数据
备份数据库的工具是 mysqldump,在使用 mysqldump 时加上 -single-transaction 参数的时候,就会在备份数据库之前先开启事务。这种方法只适用于支持「可重复读隔离级别的事务」的存储引擎,
InnoDB 存储引擎默认的事务隔离级别正是可重复读,因此可以采用这种方式来备份数据库
但是,对于 MVISAM 这种不支持事务的引擎,在备份数据库时就要使用全局锁的方法。
 
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号