MySQL 啥时候用表锁,啥时候用行锁?

大家好,我是树哥。
MySQL Innodb 的锁可以说是执行引擎的并发基础了,有了锁才能保证数据的一致性。众所周知,我们都知道 Innodb 有全局锁、表级锁、行级锁三种,但你知道什么时候会用表锁,什么时候会用行锁吗?虽然对 MySQL 的知识点挺熟悉的,但一开始看到这个问题,树哥也是有点懵,我还真没从这个角度去思考过。大家可以暂时 1 分钟思考下答案,后面我将带大家弄清楚这个问题。
对于这个问题,我只能粗略地想起一些片段,例如:
- 对于表级锁而言,当执行 DDL 语句去修改表结构时,会使用表级锁。
- 对于行级锁而言,一般情况下都会默认使用行级锁,貌似是需要有索引匹配到才行。
上面就是我粗略想到的答案,不知道大家思考的答案是否和我一样呢?下面就让我带着大家来温习下 MySQL 的锁吧!

对于数据库而言,其锁范围可以分为:
- 全局锁
- 表级锁
- 行级锁
全局锁
全局锁就是对整个数据库实例加锁。 MySQL 提供了一个加全局读锁的方法,命令是 Flush tables with read lock (FTWRL)。当你需要让整个库处于只读状态的时候,可以使用这个命令,之后其他线程的以下语句会被阻塞:数据更新语句(数据的增删改)、数据定义语句(包括建表、修改表结构等)和更新类事务的提交语句。你可以理解为,全局锁基本上把数据所所有的变更语句都锁住了。
全局锁的典型场景应用场景是全库逻辑备份,也就是把整个库每个表都 select 出来存起来。上面说到全局锁会锁住所有变更语句,但这只是对于 MyISAM 存储引擎而言的。对于 Innodb 而言,其可以利用 MVCC 实现数据的一致性视图,从而不需要锁整个库就可以实现全库的数据备份。
表级锁
表级锁可以分为:表锁、元数据锁、意向锁三种。
表锁
表锁,顾名思义就是对某个表加锁。
那什么时候会使用表锁呢?
一般情况是对应的存储引擎没有行级锁(例如:MyIASM),或者是对应的 SQL 语句没有匹配到索引。
对于第一种情况而言,因为对应存储引擎不支持行锁,所以只能是使用更粗粒度的锁来实现,这也比较好理解。
对于第二种情况而言,如果存储引擎支持行锁,但对应的 SQL 就没有使用索引,那么此时也是会全表扫描,那此时也是会使用表锁。例如下面的语句没有指定查询列,或者指定了查询列但是并没有用到索引,那么也是会直接锁定整个表。
// 没有指定查询列
select * from user;
// 指定查询列,但是没有用到索引
select * from user where name = 'zhangsan';
上面说的索引,可以说是判断是否会用行级锁的关键。但我想到一个问题:如果查询或更新用到了索引,但是查询或更新的数据特别多,占全表的 80% 甚至更多,这时候是会用表锁,还是行锁呢? 这是一个很有意思的问题,感兴趣的朋友自行弄个测试表验证一下,后续有机会我们再聊聊这个问题。
元数据锁
元数据,指的是我们的表结构这些元数据。元数据锁(Metadata Lock)自然是执行 DDL 表结构变更语句时,我们对表加上的一个锁了。
那什么时候会使用元数据锁这个表级锁呢?
当我们对一个表做增删改查操作的时候,会加上 MDL 读锁;当我们要对表结构做变更时,就会加 MDL 写锁。
意向锁
意向锁,本质上就是空间换时间的产物,是为了提高行锁效率的一个东西。
在 InnoDB 中,我们对某条记录进行锁定时,为了提高并发度,通常都只是锁定这一行记录,而不是锁定整个表。而当我们需要为整个表加 X 锁的时候,我们就需要遍历整个表的记录,如果每条记录都没有被加锁,才可以给整个表加 X 锁。而这个遍历过程就很费时间,这时候就有了意向锁的诞生。
意向锁其实就是标记这个表有没有被锁,如果有某条记录被锁住了,那么就必须获取该表的意向锁。所以当我们需要判断这个表的记录有没有被加锁时,直接判断意向锁就可以了,减少了遍历的时间,提高了效率,是典型的用空间换时间的做法。
那么什么时候会用到意向锁呢?
很简单,就是在对表中的行记录加锁的时候,就会用到意向锁。
行级锁
千呼万唤,终于来到了行级锁。
要知道的是,行级锁是存储引擎级别的锁,需要存储引擎支持才有效。目前 MyISAM 存储引擎不支持行级锁,而 Innodb 存储引擎则支持行级锁。而全局锁、表级锁,则是 MySQL 层面就支持的锁。
那么什么时候会使用行级锁呢?
当增删改查匹配到索引时,Innodb 会使用行级锁。
如果没有匹配不到索引,那么就会直接使用表级锁。
总结
文章最后,我们回顾一下开头提出的问题:Innodb 啥时候用表锁,啥时候用行锁?
表级锁包括:表锁、元数据锁、意向锁。
对于表锁而言,当存储引擎不支持行级锁时,使用表锁。SQL 语句没有匹配到索引时,使用表锁。
对于元数据锁而言,对表做增删改查时,会加上 MDL 读锁。对表结构做变更时,会加上 MDL 写锁。
对于意向锁而言,对表中的行记录加锁时,会用到意向锁。
而对于行级锁而言,增删改查匹配到索引时,会使用行级锁。
最后,附上本文的思维导图,方便大家回顾本文内容~
如果你喜欢今天的分享,记得一键三连支持我!

MySQL 啥时候用表锁,啥时候用行锁?的更多相关文章
- MySQL中锁详解(行锁、表锁、页锁、悲观锁、乐观锁等)
原文地址:http://blog.csdn.net/mysteryhaohao/article/details/51669741 锁,在现实生活中是为我们想要隐藏于外界所使用的一种工具.在计算机中,是 ...
- MySQL锁(三)行锁:幻读是什么?如何解决幻读?
概述 前面两篇文章介绍了MySQL的全局锁和表级锁,今天就介绍一下MySQL的行锁. MySQL的行锁是各个引擎内部实现的,不是所有的引擎支持行锁,例如MyISAM就不支持行锁. 不支持行锁就意味着在 ...
- MySQL锁:03.InnoDB行锁
目录 InnoDB 行锁 锁排查可以用的视图和数据字典 InnoDB 行锁兼容性 InnoDB行锁之共享锁 共享锁: 查看InnoDB锁 InnoDB行锁实现机制 对普通索引上锁 InnoDB隐式.显 ...
- MySQL锁(四)行锁的加锁规则和案例
在上一篇文章,我们学习了间隙锁和next-key lock,但是不知道怎么加锁,有哪些规则.间隙锁的概念不太好理解,尤其是配合上行锁后,很容易在判断是否会出现锁等待的问题上犯错. 今天我们就来学习一下 ...
- MySQL中的锁(表锁、行锁)
锁是计算机协调多个进程或纯线程并发访问某一资源的机制.在数据库中,除传统的计算资源(CPU.RAM.I/O)的争用以外,数据也是一种供许多用户共享的资源.如何保证数据并发访问的一致性.有效性是所在有数 ...
- mysql 实验论证 innodb表级锁与行级锁
innodb 的行锁是在有索引的情况下,没有索引的表是锁定全表的. 表锁演示(无索引) Session1: mysql> set autocommit=0; mysql> select * ...
- MySQL 行锁 表锁机制
MySQL 表锁和行锁机制 行锁变表锁,是福还是坑?如果你不清楚MySQL加锁的原理,你会被它整的很惨!不知坑在何方?没事,我来给你们标记几个坑.遇到了可别乱踩.通过本章内容,带你学习MySQL的行锁 ...
- [转]MySQL 表锁和行锁机制
本文转自:http://www.cnblogs.com/itdragon/p/8194622.html MySQL 表锁和行锁机制 行锁变表锁,是福还是坑?如果你不清楚MySQL加锁的原理,你会被它整 ...
- Mysql MyISAM与InnoDB 表锁行锁以及分库分表优化
一. 两种存储引擎:MyISAM与InnoDB 区别与作用 1. count运算上的区别: 因为MyISAM缓存有表meta-data(行数等),因此在做COUNT(*)时对于一个结构很好的查询是不需 ...
- MySQL学习之——锁(行锁、表锁、页锁、乐观锁、悲观锁等)
转载. https://blog.csdn.net/mysteryhaohao/article/details/51669741 锁,在现实生活中是为我们想要隐藏于外界所使用的一种工具.在计算机中,是 ...
随机推荐
- 视网膜血管分割代码(Pytorch实现)
创建日期: 2021-12-24 17:00:00 update log(2021.12.24):B站视频删除了,回放看了一下,讲的不太行......2333,时间过得真快,转眼就是2022年了啊 2 ...
- 手脱MoleBox(2.3.3-2.6.4)
1.查壳 2.找到OEP 对第二个Call使用ESP定律,再跳转后的位置进入第一个Call,这里就是OEP了,在这里直接dump的话会失败,那是因为MoleBox壳对IAT进行二次跳转,我们先在OEP ...
- PyScript:让Python在HTML中运行
大家好,我是DD,已经是封闭在家的第51天了! 最近一直在更新Java新特性和IDEA Tips两个专栏,其他方向内容的动态关注少了.昨天天晚上刷推的时候,瞄到了这个神奇的东西,觉得挺cool的,拿出 ...
- opencv学习之基础
前段时间一直在钻研深度学习中的卷积神经网络,其中的预处理环节可以说非常关键,主要就是对图片和视频进行处理.而图像处理就涉及到图形学和底层技术细节,这是一个比较精深和专业的领域,假设我们要从头开始做起, ...
- 第一个Python程序 | 机选彩票号码+爬取最新开奖号码
(机选彩票号码+爬取最新开奖号码 | 2021-04-21) 学习记录,好记不如烂笔头 这个程序作用是<机选三种彩票类型的号码> 程序内包含功能有如下: 自动获取最新的三种彩票的开奖号码 ...
- JS 异步与 Promise
JS 异步与 Promise 本文写于 2020 年 6 月 8 日 1. 同步与异步与回调函数 Promise 现在是前端面试必考题呀,但是先不急着看 Promise,我们首先来看看什么是异步. - ...
- linux篇-centos7.3配置
Centos7.3防火墙配置 1.查看firewall服务状态 systemctl status firewalld 2.查看firewall的状态 firewall-cmd --state 3.开启 ...
- 哈工大软件构造Lab2(2022)
(防扒小助手) 本人CSDN博客: https://blog.csdn.net/m0_61753302https://blog.csdn.net/m0_61753302本人博客园博客(同步CSDN): ...
- C/C++ 单元自动化测试解决方案实践
vivo 互联网服务器团队 - Li Qingxin C/C++ 开发效率一直被业内开发人员诟病,单元测试开发效率也是如此,以至于开发人员不愿花时间来写单元测试.那么我们是不是可以通过改善编写单元测试 ...
- 类型转换——JavaSE基础
类型转换 类型判断 可以通过Instanceof关键字判断左操作数是否是右操作数的父类或本身 强制类型转换 不能对布尔值进行转换 不能将对象类型转换为不相关的类型 把高容量转向低容量时,需要进行强制类 ...