一条update语句到底加了多少锁?带你深入理解底层原理
迎面走来了你的面试官,身穿格子衫,挺着啤酒肚,发际线严重后移的中年男子。
手拿泡着枸杞的保温杯,胳膊夹着MacBook,MacBook上还贴着公司标语:“我爱加班”。
面试开始,直入正题。
面试官: 看你简历上面写着精通MySQL,我问你一个MySQL锁相关的问题,你看一下这条SQL会对哪些数据加锁?
update user set name='一灯' where age=5;
表结构是这样的:
CREATE TABLE `user` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
`name` varchar(255) DEFAULT NULL COMMENT '姓名',
`age` int DEFAULT NULL COMMENT '年龄',
PRIMARY KEY (`id`),
KEY `idx_age` (`age`)
) ENGINE=InnoDB COMMENT='用户表';
我: age是非唯一性索引,MySQL的锁是加在索引上面的,应该只会对age=10的数据加锁。
面试官: 确定吗?
我: 嗯...,应该是的。
面试官: 【嘲讽】,这就是你精通MySQL的水平吗?今天面试就先到这里吧,后面有消息会主动联系你。
后面还可能有消息吗?你们啥时候主动联系过我?
实话实说的被拒,八股文背得溜反而被录取。
好吧,等我看看一灯怎么总结的MySQL的八股文。
我: 这条SQL具体对哪些数据加锁,还需要看表中有哪些数据。
MySQL有三种类型的行锁:
记录锁(Record Locks):
即对某条记录加锁。
# 对id=1的用户加锁
update user set age=age+1 where id=1;
间隙锁(Gap Locks):
即对某个范围加锁,但是不包含范围的临界数据。
# 对id大于1并且小于10的用户加锁
update user set age=age+1 where id>1 and id<10;
上面SQL的加锁范围是(1,10)。
临键锁(Next-Key Locks):
由记录锁和间隙锁组成,既包含记录本身又包含范围,左开右闭区间。
# 对id大于1并且小于等于10的用户加锁
update user set age=age+1 where id>1 and id<=10;
假如表中只有这样两条数据的话:
id | name | age |
---|---|---|
1 | 张三 | 1 |
10 | 李四 | 10 |
针对age索引,很产生这样三个索引范围:
(-∞,1],(1,10],(10,+∞)
刚才的这条SQL:
update user set name='一灯' where age=5;
由于表中不存在age=5的记录,并且age=5刚好落在 (1,10] 的区间范围内,所以会对 (1,10] 的范围加锁。
我们可以用实际数据测试一下:
当我们执行update语句的时候,age=2和age=8的数据范围都被加锁了。
面试官: 小伙子回答的不错啊。如果已经存在age=5的数据,刚才的那条update语句会对哪些数据加锁?
我: 假如表中数据是这样的。
id | name | age |
---|---|---|
1 | 张三 | 1 |
5 | 一灯架构 | 5 |
10 | 李四 | 10 |
针对age索引,很产生这样四个索引范围:
(-∞,1],(1,5],(5,10],(10,+∞)
刚才的这条SQL:
update user set name='一灯' where age=5;
age=5的数据落在 (1,5] 的区间范围内,所以会对 (1,5] 的范围加锁。
你以为这就完了吗?MySQL锁为了保证数据的安全性,还会向右遍历到不满足条件为止,还会再加一个间隙锁,也就是 (5,10] 的范围。
所以,这条SQL的加锁返回是 (1,5] 和 (5,10] 。
跟刚才age=5不存在的加锁范围 (1,10] 是一样的。不信可以再用刚才的测试用例跑一遍。
面试官: 小伙子有点东西。如果我把SQL中where条件换成主键ID,加锁范围是什么样的?
update user set name='一灯' where id=5;
我: 由于锁是加在索引上面的。
如果不存在id=5的数据,加锁范围跟上条SQL是一样的, (1,10] 。
如果存在id=5的数据,MySQL的 Next-Key Locks 会退化成 Record Locks ,也就是只在id=5的这一行记录上加锁。
面试官: 小伙子,升级加薪的机会就是留给你这样的人。薪资double,明天就来上班吧。
知识点总结:
- MySQL锁是加在索引记录上面的。
- 如果是非唯一性索引,不论表中是否存在该记录,除了会对该记录所在范围加锁,还会向右遍历到不满足条件的范围进行加锁。
- 如果是唯一索引,如果表中存在该记录,只对该行记录加锁。如果表中不存在该记录,除了会对该记录所在范围加锁,还会向右遍历到不满足条件的范围进行加锁。
文章持续更新,可以微信搜一搜「 一灯架构 」第一时间阅读更多技术干货。
一条update语句到底加了多少锁?带你深入理解底层原理的更多相关文章
- 完蛋,公司被一条 update 语句干趴了!
大家好,我是小林. 昨晚在群划水的时候,看到有位读者说了这么一件事. 在这里插入图片描述 大概就是,在线上执行一条 update 语句修改数据库数据的时候,where 条件没有带上索引,导致业务直接崩 ...
- 如何将多条update语句合并为一条
需求: 如何将多条update语句合并为一条update语句:如,update table1 set col='2012' where id='2014001' update table1 ...
- Update语句到底是如何操作记录的?
经常会听到一些开发的朋友说,Update语句的操作原理是:先删后加!今天偶然想起这句话,索性验证一下.参考下面示例: USE CSDN go --新添加一个文件组和文件 ALTER DATABASE ...
- sql执行万条update语句优化
几个月没有更新笔记了,最近遇到一个坑爹的问题,顺道记录一下.. 需求是这样的:一次性修改上万条数据库. 项目是用MVC+linq的. 本来想着用 直接where() 1 var latentCusto ...
- Sql Server执行一条Update语句很慢,插入数据失败
今天同事要我修改服务器数据库里面的2条数据,查看服务器上的SQL Server数据库的时候,发现这几天数据没有添加成功,然后发现磁盘很快就满了,执行Update语句时,执行半天都提示还在执行,查询语句 ...
- MySQL45讲:一条update语句是怎样执行的
首先创建一张表: create table T(ID int primary key,c int); 如果要更新ID=2这行+1:应该这样写 update T set c=c+1 where ID=2 ...
- 用一条UPDATE语句交换两列的值
在SQL UPDATE语句中,"="右侧的值在整个UPDATE语句中都是一致的,所有更新同时发生!因此以下语句将在没有临时变量的情况下交换两列的值: UPDATE table SE ...
- 一条update语句优化小记
遇到性能问题的sql如下: sql1: UPDATE amlclientlevel a SET a.client_value = (SELECT l.client_value ...
- 执行一条sql语句update多条记录实现思路
如果你想更新多行数据,并且每行记录的各字段值都是各不一样,你会怎么办呢?本文以一个示例向大家讲解下如何实现如标题所示的情况,有此需求的朋友可以了解下 通常情况下,我们会使用以下SQL语句来更新字段值: ...
随机推荐
- java高级用法之:在JNA中使用类型映射
目录 简介 类型映射的本质 TypeMapper NativeMapped 总结 简介 JNA中有很多种映射,library的映射,函数的映射还有函数参数和返回值的映射,libary和函数的映射比较简 ...
- python基础练习题(题目 斐波那契数列II)
day16 --------------------------------------------------------------- 实例024:斐波那契数列II 题目 有一分数序列:2/1,3 ...
- k8s面试1-27
目录 1.k8s常用命令有哪些? 2.报错查看各种日志方法? 3.k8s的组建有哪些? 4.k8s中安全机制是什么? 5.常用的控制器有哪些? 6.service类型有哪些? 7.ingress-Ng ...
- Bugku练习题---MISC---easy_nbt
Bugku练习题---MISC---easy_nbt flag:flag{Do_u_kN0w_nbt?} 解题步骤: 1.观察题目,下载附件 2.通过观察题目描述和压缩包中的文件,发现这个好像是MC的 ...
- for & while &迭代器
for (int i = 0; i < 10; i++) { System.out.println("hello"); } int a=100; for (;a<110 ...
- C#语法糖系列 —— 第三篇:聊聊闭包的底层玩法
有朋友好奇为什么将 闭包 归于语法糖,这里简单声明下,C# 中的所有闭包最终都会归结于 类 和 方法,为什么这么说,因为 C# 的基因就已经决定了,如果大家了解 CLR 的话应该知道, C#中的类最终 ...
- Linux 服务器的性能参数指标总结
关注「开源Linux」,选择"设为星标" 回复「学习」,有我为您特别筛选的学习资料~ 前言 一个基于 Linux 操作系统的服务器运行的同时,也会表征出各种各样参数信息.通常来说运 ...
- vue3 vite 系统标题 系统名称统一配置
想要统一配置系统名称 或者其他的,需要在vue3中使用 vite 的环境变量 vite 的环境变量 需要创建两个文件(和 vite.config.js 文件同一目录) .env.development ...
- C# 编写一个简单易用的 Windows 截屏增强工具
半年前我开源了 DreamScene2 一个小而快并且功能强大的 Windows 动态桌面软件.有很多的人喜欢,这使我有了继续做开源的信心.这是我的第二个开源作品 ScreenshotEx 一个简单易 ...
- 评估海外pop点网络质量,批量探测到整个国家运营商ip地址段时延
1 查询当地供应商所有AS号和IP地址段,如下 可以手动复制也可以爬下来,此次测试地址不多,手动复制下来再做下格式话 61.99.128.0/17 61.99.0.0/16 61.98.96.0/20 ...