catalog

  • 加锁规则
  • 等值查询间隙锁
  • 非唯一索引等值锁
  • 主键索引范围锁
  • 非唯一索引范围锁
  • 唯一索引范围锁 bug
  • 非唯一索引上存在"等值"的例子
  • limit语句加锁
  • 关于死锁

总结

1、查询过程中访问到的对象才会加锁,而加锁的基本单位是next-key lock(前开后闭);
2、等值查询上MySQL的优化:索引上的等值查询,如果是唯一索引,next-key lock会退化为行锁,如果不是唯一索引,需要访问到第一个不满足条件的值,此时next-key lock会退化为间隙锁;
3、范围查询:无论是否是唯一索引,范围查询都需要访问到不满足条件的第一个值为止;

加锁规则

默认这里的隔离级别是可重复读。
原则1:加锁的基本单位是next-key lock。该锁的区间是前开后闭
原则2:查找过程中访问到的对象才会加锁
优化1:索引上的等值查询,给唯一索引加锁的时候,next-key lock退化为行锁
优化2:索引上的等值查询,向右遍历时且最后一个值不满足等值条件的时候,next-key lock退化为间隙锁
bug:唯一索引上的范围查询会访问到不满足条件的第一个值为止。

建表语句:

CREATE TABLE `t` (`id` int(11) NOT NULL,`c` int(11) DEFAULT NULL,`d` int(11) DEFAULT NULL,PRIMARY KEY (`id`),KEY `c` (`c`)
) ENGINE=InnoDB;insert into t values(0,0,0),(5,5,5),
(10,10,10),(15,15,15),(20,20,20),(25,25,25);

等值查询间隙锁

非唯一索引等值锁

session A给索引c上c=5这一行加上读锁。

根据原则1,加锁单位是next-key lock ,因此会给(0,5]加上next-key lock.

c是普通索引,因此访问c=5后还需要向右遍历,查到c=10才放弃。

根据原则2,访问到的都要加锁,因此要给(5,10]加上next-key lock;

同时符合优化2:等值判断,向右遍历,最后一个值不满足c=5,于是退化为间隙锁(5,10);

(前面分析的(0, 5]间隙锁还是存在的,合起来存在(0, 5]和(5, 10)两个间隙锁 )

根据原则2,只有访问到的对象才会加锁,这个查询使用的是覆盖索引,并不需要访问主键索引,所以主键索引上没有加任何锁,所以session B的update语句可以执行完成。

**访问到的对象才会加锁,这个“对象”指的是列,不是 记录行。 补充一下: 加锁,是加在索引上的。 列上,有索引,就加在索引上; 列上,没有索引,就加在主键上; **

session C要插入(7,7,7)记录,会被session A 的间隙锁(5,10)锁住。

lock in share mode 只锁覆盖索引,for update 会顺便给主键索引上满足条件的行加上行锁。

总结:

锁是加在索引上的;

用lock in share mode 来给行加读锁避免数据被更新的话,就必须绕过覆盖索引的优化,在查询字段中加入索引中不存在的字段。

如将session A的语句:

select id from t where c=5 lock in share mode;

修改为

select d from t where c = 5 lock in share mode;

数据行加读锁,如果查询字段使用了覆盖索引,访问到的对象只有普通索引,并没有访问到主键索引,则不会锁主键索引。如果没有使用覆盖索引,且当前查询是for update ,update 和 delete 都是当前读,则会回表查询,访问到主键索引,这样主键索引也会加锁。

主键索引范围锁

对于表t,有两个查询语句,这两个语句加锁范围不同:

select * from t where id = 10 for update;
select * from t where id >= 10 and id < 11 for update;

这两句话逻辑上等价,但是加锁规则不一样。

执行流程:

1、找到第一个id=10的行,因此本该是next-key lock (5,10]。根据优化1,主键id上的等值条件,退化成行锁,只加id = 10这一行的行锁

2、范围查找继续往后找,找到id=15这一行停下来,因此需要加next-key lock (10,15].

所以,session A这时候锁的范围就是主键索引上,行锁id = 10和next-key lock(10,15]。 因为是范围查询,不是等值查询,所以不会进行优化2; 所以会出现B C的block情况。

需要注意 首次session A 定位查找id=10的行时候,是当作等值查询来判断的,而向右扫描到id=15的时候,用的是范围查询判断。

--引用:
1. 先走主键id索引, 拿出id=10的那一行, (注意这里是等值查询) 2. 再从id=10的那一行开始, 不断地往右遍历拿出每一行, 直到它的 id 不满足 大于等于10, 小于11 这个条件后, 再停止 (注意这里就是范围查询) 根据一开始的Creae table/ insert values等语句(10后面就是15), 还有再根据加锁规则(原则1, 原则2, 优化1, 优化2, bug5): 执行步骤1时, 因为是等值查询, 主键索引又是唯一索引, 根据原则1, 原则2, 优化1, 最终只加行锁10; 执行步骤2时, 因为是范围查询, 主键索引又是唯一索引, 根据原则1, 原则2, Bug5, 而不满足条件的第一个值就是15, 所以最终要加锁(10, 15]; 这一块相对还是比较繁琐的

非唯一索引范围锁

唯一索引范围锁 bug

非唯一索引上存在"等值"的例子

给表t插入一条新纪录

insert into t values(30,10,30);

此时表里面就有了两个c=10的行。 因为主键是唯一的, 所以不存在完全相同的两行 ,此时的索引c为:

两个c=10,但是主键id不同(分别为10和30),因此这两个c=10的记录之间也是有间隙的。
这里使用delete语句来验证。delete原则和之前update原则一样。

session A遍历的时候,先访问第一个c=10的记录。根据原则1:这里加的是

(c = 5,id = 5) 到(c = 10,id = 10)这个next-key lock.

然后,session A向右查找,直到碰到(c=15,id=15)这一行,循环才结束。根据优化2,这是一个等值查询,向右查找到了不满足条件的行,所以会退化成(c=10,id=10)到(c=15,id=15)的间隙锁。

也就是说,这个delete语句在索引c上的加锁范围,如下:

注意(c=5,id=5)和(c=15,id=15)这两行都没有锁。

limit语句加锁

关于死锁

next-key lock实际上是间隙锁和行锁加起来的结果。


分析流程:

1、session A启动事务执行查询语句加lock in share mode,在索引c上加了next-key lock(5,10]和间隙锁(10,15);

2、session B的update语句在索引c上加next-key lock(5,10],进入锁等待;

3、然后session A要再插入(8,8,8)这一行,被session B的间隙锁锁住。由于出现了死锁,InnoDB让session B回滚。

我们认为session B的加锁还没申请成功。

但是,其实session B的"加next-key lock(5,10]"操作实际上分成了两步,先是加(5,10)的间隙锁,加锁成功;然后加c=10的行锁,第二步才被锁住。

也就是说我们分析加锁的具体步骤时,需要分成间隙锁和行锁两段来执行。

《MySQL——加锁规则(待补全,有些没看懂)》相关推荐

  1. ComeFuture英伽学院——2020年 全国大学生英语竞赛【C类初赛真题解析】(持续更新)

    视频:ComeFuture英伽学院--2019年 全国大学生英语竞赛[C类初赛真题解析]大小作文--详细解析 课件:[课件]2019年大学生英语竞赛C类初赛.pdf 视频:2020年全国大学生英语竞赛 ...

  2. ComeFuture英伽学院——2019年 全国大学生英语竞赛【C类初赛真题解析】大小作文——详细解析

    视频:ComeFuture英伽学院--2019年 全国大学生英语竞赛[C类初赛真题解析]大小作文--详细解析 课件:[课件]2019年大学生英语竞赛C类初赛.pdf 视频:2020年全国大学生英语竞赛 ...

  3. 信息学奥赛真题解析(玩具谜题)

    玩具谜题(2016年信息学奥赛提高组真题) 题目描述 小南有一套可爱的玩具小人, 它们各有不同的职业.有一天, 这些玩具小人把小南的眼镜藏了起来.小南发现玩具小人们围成了一个圈,它们有的面朝圈内,有的 ...

  4. 信息学奥赛之初赛 第1轮 讲解(01-08课)

    信息学奥赛之初赛讲解 01 计算机概述 系统基本结构 信息学奥赛之初赛讲解 01 计算机概述 系统基本结构_哔哩哔哩_bilibili 信息学奥赛之初赛讲解 02 软件系统 计算机语言 进制转换 信息 ...

  5. 信息学奥赛一本通习题答案(五)

    最近在给小学生做C++的入门培训,用的教程是信息学奥赛一本通,刷题网址 http://ybt.ssoier.cn:8088/index.php 现将部分习题的答案放在博客上,希望能给其他有需要的人带来 ...

  6. 信息学奥赛一本通习题答案(三)

    最近在给小学生做C++的入门培训,用的教程是信息学奥赛一本通,刷题网址 http://ybt.ssoier.cn:8088/index.php 现将部分习题的答案放在博客上,希望能给其他有需要的人带来 ...

  7. 信息学奥赛一本通 提高篇 第六部分 数学基础 相关的真题

    第1章   快速幂 1875:[13NOIP提高组]转圈游戏 信息学奥赛一本通(C++版)在线评测系统 第2 章  素数 第 3 章  约数 第 4 章  同余问题 第 5 章  矩阵乘法 第 6 章 ...

  8. 信息学奥赛一本通题目代码(非题库)

    为了完善自己学c++,很多人都去读相关文献,就比如<信息学奥赛一本通>,可又对题目无从下手,从今天开始,我将把书上的题目一 一的解析下来,可以做参考,如果有错,可以告诉我,将在下次解析里重 ...

  9. 信息学奥赛一本通(C++版) 刷题 记录

    总目录详见:https://blog.csdn.net/mrcrack/article/details/86501716 信息学奥赛一本通(C++版) 刷题 记录 http://ybt.ssoier. ...

  10. 最近公共祖先三种算法详解 + 模板题 建议新手收藏 例题: 信息学奥赛一本通 祖孙询问 距离

    首先什么是最近公共祖先?? 如图:红色节点的祖先为红色的1, 2, 3. 绿色节点的祖先为绿色的1, 2, 3, 4. 他们的最近公共祖先即他们最先相交的地方,如在上图中黄色的点就是他们的最近公共祖先 ...

最新文章

  1. es获取最大时间的记录_ES查询一段时间内某一循环时间段的数据
  2. 2016-2017-1 《信息安全系统设计基础》 学生博客及Git@OSC 链接
  3. 最简单的日历控件“星期几”变为“几”
  4. 谷歌开源预训练新范式BiT,准确率提高近25%!网友评价:CV界的BERT
  5. 理解 pkg-config 工具
  6. 乘风破浪:LeetCode真题_008_String to Integer (atoi)
  7. php怎么异步执行,php怎么实现异步
  8. STM32——串口通信原理
  9. 如何从seo的维度来选择网站的关键词
  10. 微信小程序——调查问卷案例
  11. 基于RFID定位技术的智能仓储管理系统--RFID智能仓储--新导智能
  12. css网站常用字体,网站常用字体那些事
  13. 【Edge浏览器】插件安装失败[Download Interrupt]
  14. 【WINRAR安装和使用教程】常用压缩软件
  15. 郑州大学计算机新媒体专业介绍,专业介绍:网络与新媒体专业
  16. android百度地图API 骑行,步行导航的DEMO以及途径点问题
  17. Scratch课程设计(一)
  18. 【迅为iMX6Q】开发板烧写Uboot后串口无任何输出的问题解决
  19. 计算机专业去支教学到什么,支教的收获及感悟4篇_大学生支教感想
  20. iOS给按钮添加系统声音

热门文章

  1. 关于一些常见智柜问题的分析及解决办法
  2. php 弹出变量,php取变量出现Notice: Undefined variable 的解决方法
  3. Antd Table树形展示,分页后有时候数据渲染不出的问题
  4. a标签点击跳转失效--IE6、7的奇葩bug
  5. 一个关于fixed抖动的小bug
  6. css用一张大图片来设置背景的技术真相
  7. 【HTML基础】表格和表单
  8. css正則匹配、模糊匹配
  9. 关于HTML的面试题-html5/css3篇
  10. centos7.3 安装 mysql-5.7.13