大家好,我是小林 。
最近重新补充了《MySQL 有哪些锁》文章内容:
- 增加记录锁、间隙锁、net-key 锁
- 增加插入意向锁
- 增加自增锁为 innodb_autoinc_lock_mode = 2 模式时,为什么主从环境会有不安全问题的说明
这次 , 来说说 MySQL 的锁,主要是 Q&A 的形式,看起来会比较轻松 。
不多 BB 了 , 发车!
在 MySQL 里,根据加锁的范围 , 可以分为全局锁、表级锁和行锁三类 。
文章插图
全局锁
全局锁是怎么用的?要使用全局锁 , 则要执行这条命:
flush tables with read lock
执行后 , 整个数据库就处于只读状态了,这时其他线程执行以下操作,都会被阻塞:- 对数据的增删改操作,比如 insert、delete、update等语句;
- 对表结构的更改操作,比如 alter table、drop table 等语句 。
unlock tables
当然,当会话断开了,全局锁会被自动释放 。全局锁应用场景是什么?全局锁主要应用于做全库逻辑备份,这样在备份数据库期间,不会因为数据或表结构的更新 , 而出现备份文件的数据与预期的不一样 。
举个例子大家就知道了 。
在全库逻辑备份期间,假设不加全局锁的场景 , 看看会出现什么意外的情况 。
如果在全库逻辑备份期间,有用户购买了一件商品,一般购买商品的业务逻辑是会涉及到多张数据库表的更新 , 比如在用户表更新该用户的余额 , 然后在商品表更新被购买的商品的库存 。
那么,有可能出现这样的顺序:
- 先备份了用户表的数据;
- 然后有用户发起了购买商品的操作;
- 接着再备份商品表的数据 。
这种情况下,备份的结果是用户表中该用户的余额并没有扣除,反而商品表中该商品的库存被减少了,如果后面用这个备份文件恢复数据库数据的话,用户钱没少 , 而库存少了,等于用户白嫖了一件商品 。
所以,在全库逻辑备份期间,加上全局锁,就不会出现上面这种情况了 。
加全局锁又会带来什么缺点呢?加上全局锁,意味着整个数据库都是只读状态 。
那么如果数据库里有很多数据,备份就会花费很多的时间,关键是备份期间 , 业务只能读数据 , 而不能更新数据,这样会造成业务停滞 。
既然备份数据库数据的时候 , 使用全局锁会影响业务,那有什么其他方式可以避免?有的 , 如果数据库的引擎支持的事务支持可重复读的隔离级别,那么在备份数据库之前先开启事务,会先创建 Read View,然后整个事务执行期间都在用这个 Read View,而且由于 MVCC 的支持 , 备份期间业务依然可以对数据进行更新操作 。
因为在可重复读的隔离级别下,即使其他事务更新了表的数据 , 也不会影响备份数据库时的 Read View,这就是事务四大特性中的隔离性,这样备份期间备份的数据一直是在开启事务时的数据 。
备份数据库的工具是 mysqldump,在使用 mysqldump 时加上
–single-transaction
参数的时候 , 就会在备份数据库之前先开启事务 。这种方法只适用于支持「可重复读隔离级别的事务」的存储引擎 。InnoDB 存储引擎默认的事务隔离级别正是可重复读,因此可以采用这种方式来备份数据库 。
但是,对于 MyISAM 这种不支持事务的引擎,在备份数据库时就要使用全局锁的方法 。
表级锁
MySQL 表级锁有哪些?具体怎么用的 。MySQL 里面表级别的锁有这几种:
- 表锁;
- 元数据锁(MDL);
- 意向锁;
- AUTO-INC 锁;
如果我们想对学生表(t_student)加表锁 , 可以使用下面的命令:
//表级别的共享锁 , 也就是读锁;lock tables t_student read;//表级别的独占锁 , 也就是写锁;lock tables t_stuent write;
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- SpringCloud整合分布式事务Seata 1.4.1 支持微服务全局异常拦截
- llinux下mysql建库、新建用户、用户授权、修改用户密码
- 别惹农夫小炎子皮肤怎么解锁
- RedHat7.6安装mysql8步骤
- 别惹农夫药尊者皮肤怎么解锁
- 保险柜怎么开锁(学保险柜开锁技术)
- 再有人说synchronized是重量级锁,就把这篇文章扔给他看
- 究极无敌细节版 Mysql索引
- 原神千柱的花园怎么解锁
- Mysql通过Canal同步Elasticsearch