Mysql学习笔记-临键锁实验
前言
昨天同事跟我聊到一个问题:InnoDB里面间隙锁锁住的数据可以update么?我们经常都说间隙锁是InnoDB在RR隔离级别下防止幻读的一种处理手段。它可以防止数据在间隙范围中insert数据,但是对于update?很多资料都没有明显说明,今天咱们就通过几个实验来揭开间隙锁的神秘面纱。
mysql命令
- 查看自动提交事务开关状态:show variables like 'autocommit';
- 关闭自动事务:set autocommit = 0;
- 查看事务隔离级别:show variables like 'transaction%';
- 设置事务隔离级别:set session transaction isolation level read committed;
- 查看当前服务器锁情况:select * from performance_schema.data_locks;
环境
Mysql Server 8.0.28 / InnoDB / RR
实验表
CREATE TABLE `user` (
`id` bigint NOT NULL AUTO_INCREMENT,
`card` varchar(18) DEFAULT NULL,
`name` varchar(20) DEFAULT NULL,
`sex` int DEFAULT NULL,
`age` int DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
初始化数据

下面让我们开启实验
实验一:foru update查询下,主键更新
sql
-- 事务一:主键写锁查询,左开右开
select * from user where id > 3 and id < 8 for update;
-- 事务二:范围内更新,根据主键更新值
update user set name = 1 where id = 7;
实验结果(锁冲突等待)

结果分析:
- 红框部分为更新事务,持有IX锁,等待行锁获取,行锁加锁对象为主键索引7;
- 非红框部分为查询事务,范围内记录均持有X锁(临键锁),锁定的都是LOCK_DATA值前面的间隙和值本身,但是主键索引为8的数据,不包含本身。
示意图如下

ps:
x:间隙锁(左开右闭),即临键锁
x,GAP:间隙锁(双端开口)
X,REC_NOT_GAP:记录锁即行锁
实验二:foru update查询下,不使用索引
sql
-- 事务一:非索引写锁查询,左开右闭
select * from user where age > 18 and age <= 40 for update;
-- 事务二:非索引更新,此条记录主键:6,age:33
update user set sex = 1 where name ='吴八';
实验结果(锁冲突等待)

结果分析:
1、由于查询和更新均未使用索引,导致锁全表。
2、查询事务全部获取临键锁
3、更新事务由于全表锁,所以从主键最小的节点开始等待获取锁
示意图如下

注意:由于查询事务会把主键最小节点前面间隙也都的都锁上
实验三:辅助索引写锁查询,非索引更新
sql
-- 事务一:二级索引写锁查询,左开右闭
select * from user where card > '0002' and card <= '0008' for update;3
-- 事务二:非索引更新,此条记录主键:3,card:0005
update user set sex = 1 where name ='王五';
实验结果(锁等待冲突)

结果分析
- 查询事务对于辅助索引增加临键锁,对于辅助索引对应的主键增加行锁。
- 由于我们查询区间为左开右闭,查询事务还会给临界索引数据的后一个节点加上临键锁。然后由于000x不在查询范围内,所以主键锁定不包含000x辅助索引对应的主键。
- 更新事务由于无索引,走全表,从主键最小节点开始逐步加锁,1和2都获取到了,3开始等待。
示意图如下:

小结:
1、间隙锁范围内部数据其他事务需要等待锁,否则无法修改、插入、删除。
2、对于查询或者更新条件包含主键索引的数据会加行锁或临键锁(行锁+间隙锁)。
3、对于查询或者更新条件为辅助索引的数据会加行锁或临键锁(行锁+间隙锁)。对于左开右闭区间的索引范围查询更改,间隙锁边界会后移一个节点,参考实验二。
4、对于查询或者更新条件不包含索引的数据会锁全表(所有行记录的临键锁),等待事务会从主键最小节点逐步尝试加锁,获取不到则进入等待。
5、等值查询带索引使用行锁,范围查询或者无索引情况下,使用临键锁,全表锁也是体现在每一行上面加临键锁。
6、lock in share mode和for update类似,对于上述例子基本没有区别,唯一区别只是查询事务获取的意向锁由IX变为IS。(如果两个都是查询的话,lock in share mode不会被阻塞,共享锁,也就是读锁可以重入)。
ps:大家常说的 next-key lock其实就是临键锁,左边的间隙锁 + 右边行的行锁。
还有很多场景没有去做实验,一是太多实验写起来费事,看起来也费事,二是我觉得绝大场景都可以通过以上三个例子推导出来,比如查有索引、更新也有索引,那就是锁定指定的索引,如果是二级索引还需要锁定对应的主键索引。如果大家对间隙锁还有不明白的,可以留言一起讨论下。有需要实验的也可以留言给我,我帮你实现图片!
愿每一个人都能找到自己心中的方向!
关注我的公众号

Mysql学习笔记-临键锁实验的更多相关文章
- MySQL学习笔记-锁相关话题
在事务相关话题中,已经提到事务隔离性依靠锁机制实现的.在本篇中围绕着InnoDB与MyISAM锁机制的不同展开,进而描述锁的实现方式,多种锁的概念,以及死锁产生的原因. Mysql常用存储引擎的锁 ...
- 数据库MySQL学习笔记高级篇
数据库MySQL学习笔记高级篇 写在前面 学习链接:数据库 MySQL 视频教程全集 1. mysql的架构介绍 mysql简介 概述 高级Mysql 完整的mysql优化需要很深的功底,大公司甚至有 ...
- 一千行MySQL学习笔记 (转)
出处: 一千行MySQL学习笔记 /* 启动MySQL */ net start mysql /* 连接与断开服务器 */ mysql -h 地址 -P 端口 -u 用户名 -p 密码 /* 跳过权 ...
- mysql basic operation,mysql总结,对mysql经常使用语句的详细总结,MySQL学习笔记
mysql> select * from wifi_data where dev_id like "0023-AABBCCCCBBAA" ; 1.显示数据库列表.show d ...
- Mysql学习笔记(三)对表数据的增删改查。
正文内容. 这一部分是最简单的,也是最麻烦的.简单是因为其实只包括增删该插四个部分.大体上看,增加数据.删除数据.修改数据.查询数据都不麻烦啊,我们日常都是常用的.这个谁不会呢?以前在培训机构学mys ...
- MySQL学习笔记一
MySQL 学习笔记 一 一.数据库简单介绍 1. 按照数据库的发展时间顺序,主要出现了以下类型数据库系统: Ø 网状型数据库 Ø 层次型数据库 Ø 关系型数据库 Ø 面向对象数据库 上面4中数据库系 ...
- Mysql学习笔记(一)数据类型
原文:Mysql学习笔记(一)数据类型 学习内容: Mysql基本数据类型. 1.数字类型.. i.整型 Mysql数据类型 含义(有符号) tinyint(m ...
- MySQL学习笔记-事务相关话题
事务机制 事务(Transaction)是数据库区别于文件系统的重要特性之一.事务会把数据库从一种一致状态转换为另一个种一致状态.在数据库提交工作时,可以确保其要么所有修改都已经保存了,要么所有修改都 ...
- MySQL学习笔记-数据库内存
数据库内存 InnoDB存储引擎内存由以下几个部分组成:缓冲池(buffer pool).重做日志缓冲池(redo log buffer)以及额外的内存池(additional memory pool ...
随机推荐
- python好用的函数或对象
1.ljust.rjust "hello".ljust(10,"x") #将字符串hello做对齐,并且用字符'x'补到10个字符 #输出为:helloxxxx ...
- v-model指令的学习
v-model的原理 v-model="message" ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓就相当于先用一个v-bind绑定一个 ...
- MySQL让人又爱又恨的多表查询
1. 前言 在SQL开发当中,多表联查是绝对绕不开的一种技能.同样的查询结果不同的写法其运行效率也是千差万别. 在实际开发当中,我见过(好像还写过~)不少又长又臭的查询SQL,数据量一上来查个十几分钟 ...
- Java课程设计---数据库工具类
接下来看看传统的查询方式(一个完整的查询) package com.java.mysql; import java.sql.Connection; import java.sql.DriverMana ...
- MySQL 学习笔记(二)MVCC 机制
之前在讲 MySQL 事务隔离性提到过,对于写操作给读操作的影响这种情形下发生的脏读.不可重复读.虚读问题.是通过MVCC 机制来进行解决的,那么MVCC到底是如何实现的,其内部原理是怎样的呢?我们要 ...
- Activity的创建及生命周期
- Web安全学习
项目地址(参考):https://websec.readthedocs.io/zh/latest/basic/history.html 本文只能充当目录简介,具体还要自己深入学习. 序章 Web技术演 ...
- LeetCode-093-复原 IP 地址
复原 IP 地址 题目描述:给定一个只包含数字的字符串,用以表示一个 IP 地址,返回所有可能从 s 获得的 有效 IP 地址 .你可以按任何顺序返回答案. 有效 IP 地址 正好由四个整数(每个整数 ...
- LeetCode-038-外观数列
外观数列 题目描述:给定一个正整数 n ,输出外观数列的第 n 项. 「外观数列」是一个整数序列,从数字 1 开始,序列中的每一项都是对前一项的描述. 你可以将其视作是由递归公式定义的数字字符串序列: ...
- 含变量的字符串拼接(string.Format()或$"")
含变量的字符串拼接,一般不要用 + 来连接字符串,可用以下两种方式: 一.string.Format() 二.$"" (在C#6以上的版本中可用,推荐这种写法) 1 public ...