注:加锁规则指的是next-key lock,如果还不了解next-key lock,请阅读上一篇博客

加锁规则可以概括为:两个原则、两个优化和一个bug:
原则1:加锁的基本单位是next-key lock,前开后闭
原则2:查找过程中访问到的对象才会加锁
优化1:索引上的等值查询,给唯一索引加锁的时候,next-key lock退化成行锁
优化2:索引上的等值查询,向右遍历时且最后一个值不满足等值条件的时候,next-key lock退化为间隙锁
1个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);
接下来来看几个案例:

案例一:等值查询间隙锁

 
  1. 由于数据库中没有 id=7这条数据,id又为主键索引,所以根据原则1可得:next-key lock的加锁范围是(5,10]。
  2. SessionB要往这个间隙中插入id=8的数据,会被锁住,而SessionA是一个等值查询(id=7),且SessionCid=10的查询不满足查询条件(7 != 10),根据优化2可得,此时next-key lock退化成间隙锁:(5,10)
因此,SessionB会被阻塞,SessionC不会被阻塞

案例二:非唯一索引等值锁

  1. 根据原则1,加锁的单位是next-key lock,因此会(0,5]加上next-key lock
  2. c是普通索引,所以找到c=5这一条数据后,并不会停下,而是继续向右遍历,直到c=10,根据原则2,访问到的都要进行加锁,所以要给(5,10]加上next-key lock
  3. 由于优化2,等值判断,向右遍历,最后一个值不满足c=5这个等值条件,所以next-key lock退化成间隙锁(5,10)
  4. 根据原则2,访问到的数据才会加锁,又因为SessionB这个查询使用了覆盖索引,只需要访问主键索引,而主键索引并没有加锁,所以SessionB可以执行。(锁是加在索引上的)SessionC要插入的元素位于(5,10)这个间隙锁的范围内,所以会被阻塞。

案例三:主键索引范围锁

  1. SessionA的语句执行时,由于id是主键索引,找到了第一行id=10的数据,所以此时的next-key lock应该为(5,10],根据优化1,主键id的等值条件,退化成行锁。
  2. 往后继续查找,到id=15这一行停下来,因此需要加next-key lock(10,15]
  3. 所以此时这个next-key lock的范围就是[10,15]

案例四:非唯一索引范围锁

 

类似于案例3,唯一不同的地方是,在第一次使用c=10定位记录的时候,索引c上加上了(5,10]的next-key lock,这个next-key lock不会退化,所以最终SessionA加的锁是,索引c上的(5,10]和(10,15]这两个next-key lock

案例五:唯一索引范围锁bug

正常来说,唯一索引的next-key lock应该是(10,15],但是由于bug1,扫描到15后,还会继续扫描第一个不符合条件的值,因此还会存在一个next-key lock范围是(15,20],这应该算是一个bug,因为(10,15]的next-key lock已经可以保证不会有范围内的数据插入。

案例六:limit语句加锁:

这两条语句的执行结果是一样的, 但是加锁范围却不一样。
c是普通索引,所以SessionA加的next-key lock的范围是(5,10]和(10,15)
但是由于这里的limit已经明确了数据量的限制,因此在遍历到(c=10,id=30)这一行数据的时候,满足条件的语句已经有2条了。所以next-key lock的范围就变成了从(c=5,id=5)到(c=10,id=30)
通过这个案例,我们可以得到一个结论,在删除数据的时候,尽量指定limit,这样不仅可以控制删除数据的条数,让操作更安全,也可以减少加锁的范围

案例七:死锁

  1. sessionA启动事务后,执行查询语句加lock in share mode,在索引C上加上了next-key lock(5,10]和间隙锁(10,15)
  2. SessionB的更新语句也要在c上加next-key lock(5,10]进入等待。
  3. SessionA要再插入 (8,8,8)这一行,被SessionB的间隙锁锁住,出现了死锁。InnoDB让SessionB回滚。
这里就有一个问题,SessionB的 next-key lock(5,10]不是没申请成功吗?为什么还会阻塞SessionA?
其实SessionB的加next-key lock(5,10]是分成两步操作的,首先加(5,10)的间隙锁,在加c=10的行锁,间隙锁不是排他锁,所以加锁成功。也就是说next-key lock是分为间隙锁和行锁两端来执行的。

你了解MySQL的加锁规则吗?的更多相关文章

  1. 聊聊MySQL的加锁规则《死磕MySQL系列 十五》

    大家好,我是咔咔 不期速成,日拱一卒 本期来聊聊MySQL的加锁规则,知道这些规则后可以判断SQL语句的加锁范围,同时也可以写出更好的SQL语句,防止幻读问题的产生,在能力范围内最大程度的提升MySQ ...

  2. MySQL Lock--INSERT加锁规则

    Insert操作加锁规则 1.INSERT操作会对新插入的记录加行锁(ROW LOCK)+排他锁(X LOCK),不会产生任何GAP锁和Next-Key锁 2.在插入记录前,会向插入记录所在位置申请意 ...

  3. MySQL Lock--MySQL加锁规则

    ===================================================================== 淘宝林晓斌总结 在可重复读事务隔离级别下,加锁规则如下: 原 ...

  4. MySQL锁(四)行锁的加锁规则和案例

    在上一篇文章,我们学习了间隙锁和next-key lock,但是不知道怎么加锁,有哪些规则.间隙锁的概念不太好理解,尤其是配合上行锁后,很容易在判断是否会出现锁等待的问题上犯错. 今天我们就来学习一下 ...

  5. MySQL Lock--MySQL加锁学习2

    准备测试数据: ## 开启InnoDB Monitor SET GLOBAL innodb_status_output=ON; SET GLOBAL innodb_status_output_lock ...

  6. MySQL Lock--MySQL加锁学习1

    准备测试数据: ## 开启InnoDB Monitor SET GLOBAL innodb_status_output=ON; SET GLOBAL innodb_status_output_lock ...

  7. SQL Server 与MySQL中排序规则与字符集相关知识的一点总结

    字符集&&排序规则 字符集是针对不同语言的字符编码的集合,比如UTF-8字符集,GBK字符集,GB2312字符集等等,不同的字符集使用不同的规则给字符进行编码排序规则则是在特定字符集的 ...

  8. JAVA程序对MYSQL数据库加锁实验

    什么是脏读,不可重复读,幻读 1. 脏读 :脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据. 2. 不可重 ...

  9. MySQL 字符集和校验规则工作流程

    MySQL 字符集和校验规则工作原理 字符编码相关参数 数据流中的转码过程 校验规则 Tips:字符集和校验规则总是相伴的 一 从简单的建库语句开始 CREATE DATABASE [IF NOT E ...

随机推荐

  1. Springboot】Springboot整合邮件服务(HTML/附件/模板-QQ、网易)

    介绍 邮件服务是常用的服务之一,作用很多,对外可以给用户发送活动.营销广告等:对内可以发送系统监控报告与告警. 本文将介绍Springboot如何整合邮件服务,并给出不同邮件服务商的整合配置. 如图所 ...

  2. Cohen-Sutherland算法

    Cohen-Sutherland算法 本算法又称为编码裁剪算法,算法的基本思想是对每 条直线段分三种情况处理: (1)若点p1和p 2完全在裁剪窗口内 “简取”之 (2)若点p1(x1,y1)和p2( ...

  3. 【LeetCode刷题】——两数之和.1

    ---恢复内容开始--- 一直想在leetcode上面刷题,但是java刚刚摸了一下门,所以迟迟没有动手,今天做了第一道题,感觉自己实在菜的不行,但是还是学到了很多东西, 就记录一下遇到的问题. 首先 ...

  4. 机器学习回顾篇(7):决策树算法(ID3、C4.5)

    .caret, .dropup > .btn > .caret { border-top-color: #000 !important; } .label { border: 1px so ...

  5. 2019.4.22 python_Flag

    想了很久  最后觉得还是对编程的知识点好好重新的拉一边 回炉重造并不可笑 虽然从C到java到php到python 有两年的时间了 但是很多知识点都是零零碎碎,没有花时间复习和记录 所以决定从pyth ...

  6. 微信小程序尺寸单位rpx以及样式相关介绍

    rpx单位是微信小程序中css的尺寸单位,rpx可以根据屏幕宽度进行自适应.规定屏幕宽为750rpx.如在 iPhone6 上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375p ...

  7. ‎Cocos2d-x 学习笔记(12) Speed Follow

    Speed Follow都是直接继承了Action. Speed对其他action进行包装,改变action的速度. Follow可用于node在scene中的运动,scene将node作为Follo ...

  8. UltraEdit等软件详细安装破解教程,附注册机(全网独家可用)

    --- title: "UltraEdit等软件详细安装破解教程,附注册机(全网独家可用)" categories: soft tags: soft author: LIUREN ...

  9. python编程系列---多个装饰器装饰一个函数的执行流程

    首先看一个例子 ''' 多个装饰器装饰一个函数 ''' # 定义第一个装饰器 def set_func1(func): def wrapper1(*args,**kwargs): print('装饰内 ...

  10. 【网络安全】SQL注入、XML注入、JSON注入和CRLF注入科普文

    目录 SQL注入 一些寻找SQL漏洞的方法 防御SQL注入 SQL注入相关的优秀博客 XML注入 什么是XML注入 预防XML注入 JSON注入 什么是JSON注入 JSON注入的防御 CRLF注入 ...