迎面走来了你的面试官,身穿格子衫,挺着啤酒肚,发际线严重后移的中年男子。

手拿泡着枸杞的保温杯,胳膊夹着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,明天就来上班吧。

知识点总结:

  1. MySQL锁是加在索引记录上面的。
  2. 如果是非唯一性索引,不论表中是否存在该记录,除了会对该记录所在范围加锁,还会向右遍历到不满足条件的范围进行加锁。
  3. 如果是唯一索引,如果表中存在该记录,只对该行记录加锁。如果表中不存在该记录,除了会对该记录所在范围加锁,还会向右遍历到不满足条件的范围进行加锁。

文章持续更新,可以微信搜一搜「 一灯架构 」第一时间阅读更多技术干货。

一条update语句到底加了多少锁?带你深入理解底层原理的更多相关文章

  1. 完蛋,公司被一条 update 语句干趴了!

    大家好,我是小林. 昨晚在群划水的时候,看到有位读者说了这么一件事. 在这里插入图片描述 大概就是,在线上执行一条 update 语句修改数据库数据的时候,where 条件没有带上索引,导致业务直接崩 ...

  2. 如何将多条update语句合并为一条

    需求: 如何将多条update语句合并为一条update语句:如,update table1 set col='2012' where id='2014001'      update table1  ...

  3. Update语句到底是如何操作记录的?

    经常会听到一些开发的朋友说,Update语句的操作原理是:先删后加!今天偶然想起这句话,索性验证一下.参考下面示例: USE CSDN go --新添加一个文件组和文件 ALTER DATABASE ...

  4. sql执行万条update语句优化

    几个月没有更新笔记了,最近遇到一个坑爹的问题,顺道记录一下.. 需求是这样的:一次性修改上万条数据库. 项目是用MVC+linq的. 本来想着用 直接where() 1 var latentCusto ...

  5. Sql Server执行一条Update语句很慢,插入数据失败

    今天同事要我修改服务器数据库里面的2条数据,查看服务器上的SQL Server数据库的时候,发现这几天数据没有添加成功,然后发现磁盘很快就满了,执行Update语句时,执行半天都提示还在执行,查询语句 ...

  6. MySQL45讲:一条update语句是怎样执行的

    首先创建一张表: create table T(ID int primary key,c int); 如果要更新ID=2这行+1:应该这样写 update T set c=c+1 where ID=2 ...

  7. 用一条UPDATE语句交换两列的值

    在SQL UPDATE语句中,"="右侧的值在整个UPDATE语句中都是一致的,所有更新同时发生!因此以下语句将在没有临时变量的情况下交换两列的值: UPDATE table SE ...

  8. 一条update语句优化小记

    遇到性能问题的sql如下: sql1: UPDATE amlclientlevel a SET    a.client_value = (SELECT l.client_value           ...

  9. 执行一条sql语句update多条记录实现思路

    如果你想更新多行数据,并且每行记录的各字段值都是各不一样,你会怎么办呢?本文以一个示例向大家讲解下如何实现如标题所示的情况,有此需求的朋友可以了解下 通常情况下,我们会使用以下SQL语句来更新字段值: ...

随机推荐

  1. gin框架使用【2.RESTFUL API使用】

    package mainimport ( "github.com/gin-gonic/gin")func main() { router := gin.Default() rout ...

  2. who 的页面制作

    1. html 结构 <!-- section: Who we are --> <section id="who"> <div class=" ...

  3. Android Studio 的蓝牙串口通信(附Demo源码下载)

    根据相关代码制作了一个开源依赖包,将以下所有的代码进行打包,直接调用即可完成所有的操作.详细说明地址如下,如果觉得有用可以GIthub点个Star支持一下: 项目官网 Kotlin版本说明文档 Jav ...

  4. 杭电2091空心三角形Java(AC)

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=2091 把三角形写入二维数组里,然后输出出来 注意事项: 1.三角形后面没有空格(每一层的后面) 2.三角形 ...

  5. FreeRTOS --(15)信号量之概述

    转载自 https://blog.csdn.net/zhoutaopower/article/details/107359095 在裸机编程中这样使用过一个变量:用于标记某个事件是否发生,或者标志一下 ...

  6. java基础4.19

    1.JAVA 的反射机制的原理. JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法:这种动态获取的信息以及动态调用对象的方 ...

  7. 真香警告!JitPack 开源库集成平台

    前言: 请各大网友尊重本人原创知识分享,谨记本人博客:南国以南i 简介 官方介绍: JitPack 是一个用于 JVM 和 Android 项目的新颖的包存储库.它按需构建 Git 项目并为您提供即用 ...

  8. 133_Power BI 报表服务器2020年1月版本更新亮点

    博客:www.jiaopengzi.com 焦棚子的文章目录 请点击下载附件 一个很长的春节假期后,居家办公. 升级了Power BI 报表服务器(2020年1月版本). 具体的升级内容见官网博客: ...

  9. 第31章 Spring bean 作用域

    每日一句 I must say a word about fear. It is life's only true opponent. Only fear can defeat life. 这里必须说 ...

  10. git指令使用

    仓库为空,本地创建git项目之后提交到仓库中1.创建项目文件夹(本地git仓库)2.在项目文件夹中右键:选择Git Bash3.初始化项目:git init -- 会出现一个.git的隐藏文件夹4.将 ...