你了解MySQL的加锁规则吗?
注:加锁规则指的是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);
案例一:等值查询间隙锁
- 由于数据库中没有 id=7这条数据,id又为主键索引,所以根据原则1可得:next-key lock的加锁范围是(5,10]。
- SessionB要往这个间隙中插入id=8的数据,会被锁住,而SessionA是一个等值查询(id=7),且SessionCid=10的查询不满足查询条件(7 != 10),根据优化2可得,此时next-key lock退化成间隙锁:(5,10)
案例二:非唯一索引等值锁

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

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

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

案例六:limit语句加锁:

案例七:死锁
- sessionA启动事务后,执行查询语句加lock in share mode,在索引C上加上了next-key lock(5,10]和间隙锁(10,15)
- SessionB的更新语句也要在c上加next-key lock(5,10]进入等待。
- SessionA要再插入 (8,8,8)这一行,被SessionB的间隙锁锁住,出现了死锁。InnoDB让SessionB回滚。
你了解MySQL的加锁规则吗?的更多相关文章
- 聊聊MySQL的加锁规则《死磕MySQL系列 十五》
大家好,我是咔咔 不期速成,日拱一卒 本期来聊聊MySQL的加锁规则,知道这些规则后可以判断SQL语句的加锁范围,同时也可以写出更好的SQL语句,防止幻读问题的产生,在能力范围内最大程度的提升MySQ ...
- MySQL Lock--INSERT加锁规则
Insert操作加锁规则 1.INSERT操作会对新插入的记录加行锁(ROW LOCK)+排他锁(X LOCK),不会产生任何GAP锁和Next-Key锁 2.在插入记录前,会向插入记录所在位置申请意 ...
- MySQL Lock--MySQL加锁规则
===================================================================== 淘宝林晓斌总结 在可重复读事务隔离级别下,加锁规则如下: 原 ...
- MySQL锁(四)行锁的加锁规则和案例
在上一篇文章,我们学习了间隙锁和next-key lock,但是不知道怎么加锁,有哪些规则.间隙锁的概念不太好理解,尤其是配合上行锁后,很容易在判断是否会出现锁等待的问题上犯错. 今天我们就来学习一下 ...
- MySQL Lock--MySQL加锁学习2
准备测试数据: ## 开启InnoDB Monitor SET GLOBAL innodb_status_output=ON; SET GLOBAL innodb_status_output_lock ...
- MySQL Lock--MySQL加锁学习1
准备测试数据: ## 开启InnoDB Monitor SET GLOBAL innodb_status_output=ON; SET GLOBAL innodb_status_output_lock ...
- SQL Server 与MySQL中排序规则与字符集相关知识的一点总结
字符集&&排序规则 字符集是针对不同语言的字符编码的集合,比如UTF-8字符集,GBK字符集,GB2312字符集等等,不同的字符集使用不同的规则给字符进行编码排序规则则是在特定字符集的 ...
- JAVA程序对MYSQL数据库加锁实验
什么是脏读,不可重复读,幻读 1. 脏读 :脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据. 2. 不可重 ...
- MySQL 字符集和校验规则工作流程
MySQL 字符集和校验规则工作原理 字符编码相关参数 数据流中的转码过程 校验规则 Tips:字符集和校验规则总是相伴的 一 从简单的建库语句开始 CREATE DATABASE [IF NOT E ...
随机推荐
- LeetCode_232-Implement Queue using Stacks
题意是使用栈实现队列:队列是先进先出,后进后出. class MyQueue { public: /** Initialize your data structure here. */ MyQueue ...
- Mapper
public static T MapTo<T>(this object obj) { if (obj == null) return default(T); Mapper.CreateM ...
- JNDI-Injection-Exploit
介绍 最近把自己之前写的JNDI注入利用工具改了一下push到了github,地址:https://github.com/welk1n/JNDI-Injection-Exploit,启动后这个工具开启 ...
- Linux之常用命令I
一.Linux简介 1)Minix(只为教学,开源的)-->Linux(以前者为模板,添加了一些软件) 2)Linux分为内核版本和发行版本 区别:Linux内核版本就是核心版本,不用最新版本, ...
- Oracle11g入门
数据类型 数据类型 表示 数字 number 日期时间 date 字符串 char(长度)/varchar2(长度) 约束条件 名称 约束 唯一 unique 非空约束 not null 主键约束 p ...
- Python之selenium+pytesseract 实现识别验证码自动化登录脚本
今天写自己的爆破靶场WP时候,遇到有验证码的网站除了使用pkav的工具我们同样可以通过py强大的第三方库来实现识别验证码+后台登录爆破,这里做个笔记~~~ 0x01关于selenium seleniu ...
- python中的随机函数
python--随机函数(random,uniform,randint,randrange,shuffle,sample) 本文转载自:[chamie] random() random()方法:返回随 ...
- 简单认识JVM
准备: 在具体聊JVM之前,我们先看两张图,通过分析图,咱们慢慢来聊聊JVM. JVM内存结构图 JVM内存结构脑图 上面两张图中,第二张图相对来说比较直观,就是JVM内存结构都划分成了哪些模块,各个 ...
- JVM 知识点补充——永久代和元空间
之前已经讲过了不少有关 JVM 的内容,今天准备将之前没有细讲的部分进行补充,比如:永久代和元空间. 永久代 Java 的内存中有一块称之为方法区的部分,在 JDK8 之前, Hotspot 虚拟机中 ...
- django-URL别名的作用(六)
接include函数那一节. 作用:为url地址取一个名称,这样在html中引用的时候,无论后台url怎么变,都可以访问到对应的界面,可以减少更改的次数. 基本目录: book\urls.py fro ...