mysql间隙锁 转
前面一文 mysql锁 介绍了mysql innodb存储引擎的各种锁,本文介绍一下innodb存储引擎的间隙锁,就以下问题展开讨论
1.什么是间隙锁?间隙锁是怎样产生的?
2.间隙锁有什么作用?
3.使用间隙锁有什么隐患?
一、间隙锁的基本概念
1.什么叫间隙锁
当我们用范围条件而不是相等条件检索数据,并请求共享或排他锁时,InnoDB会给符合条件的已有数据记录的索引项加锁;对于键值在条件范围内但不存在的记录,叫做“间隙(GAP)”,InnoDB也会对这个“间隙”加锁,这种锁机制就是所谓的间隙锁(NEXT-KEY)锁。
2.间隙锁的产生
上面的文字很抽象,现在举个栗子,介绍间隙锁是怎么产生的:
假设有以下表t_student:(其中id为PK,name为非唯一索引)
id | name | sex | address |
1 | zhaoyi | 0 | beijin |
3 | sunsan | 1 | shanghai |
4 | lisi | 0 | guangzhou |
5 | zhouwu | 0 | shenzhen |
6 | wuliu | 1 | hangzhou |
这个时候我们发出一条这样的加锁sql语句:
select id,name from t_student where id > 0 and id < 5 for update;
这时候,我们命中的数据为以下着色部分:
id | name | sex | address |
1 | zhaoyi | 0 | beijin |
3 | sunsan | 1 | shanghai |
4 | lisi | 0 | guangzhou |
5 | zhouwu | 0 | shenzhen |
6 | wuliu | 1 | hangzhou |
细心的朋友可能就会发现,这里缺少了条id为2的记录,我们的重点就在这里。
select ... for update这条语句,是会对数据记录加锁的,这里因为命中了索引,加的是行锁。从数据记录来看,这里排它锁锁住数据是id为1、3和4的这3条数据。
但是,看看前面我们的介绍——对于键值在条件范围内但不存在的记录,叫做“间隙(GAP)”,InnoDB也会对这个“间隙”加锁。
好了,我们这里,键值在条件范围但是不存在的记录,就是id为2的记录,这里会对id为2数据加上间隙锁。假设这时候如果有id=2的记录insert进来了,是要等到这个事务结束以后才会执行的
二、间隙锁的作用
总的来说,有2个作用:防止幻读和防止数据误删/改
1.防止幻读
关于幻读的概念可以参考我这篇文章 https://blog.csdn.net/mweibiao/article/details/80805031 ,这里就不多做解释了
假设有下面场景
时间 | 事务A | 事务B |
T1 | select count(1) from t_student where id > 1; | |
T2 | insert into t_student values(2,'qianer',1,'nanjing'); | |
T3 | commit; | |
T4 | select count(1) from t_student where id > 1; | |
T5 | commit; |
如果没有间隙锁,事务A在T1和T4读到的结果是不一样的,有了间隙锁,读的就是一样的了
2.防止数据误删/改
这个作用比较重要,假设以下场景:
时间 | 事务A | 事务B |
T1 | delete from t_student where id < 4; | |
T2 | insert into t_student values(2,'qianer',1,'nanjing'); | |
T3 | commit; | |
T4 | commit; |
这种情况下,如果没有间隙锁,会出现的问题是:id为2的记录,刚加进去,就被删除了,这种情况有时候对业务,是致命性的打击。加了间隙锁之后,由于insert语句要等待事务A执行完之后释放锁,避免了这种情况
三.使用间隙锁的隐患
最大的隐患就是性能问题
前面提到,假设这时候如果有id=2的记录insert进来了,是要等到这个事务结束以后才会执行的,假设是这种场景
时间 | 事务A | 事务B |
T1 | select * from t_student where id>1 and id < 100 for update; | |
T2 | insert into t_student values(2,'qianer',1,'nanjing'); | |
T3 | update t_student set xxxx where id=xxx; | |
T4 | update t_student set xxxx where id=xxx; | |
T5 | update t_student set xxxx where id=xxx; | |
T6 | … | |
T7 | commit; |
这种情况,对插入的性能就有很大影响了,必须等到事务结束才能进行插入,性能大打折扣
更有甚者,如果间隙锁出现死锁的情况下,会更隐晦,更难定位
原文 https://www.cnblogs.com/billmiao/p/9872161.html
mysql间隙锁 转的更多相关文章
- MySQL 间隙锁
一.根据案例二:不同索引加锁顺序的问题,模拟重现死锁(详细操作步骤) 1.RR级别下,更新操作默认会加行级锁,行级锁会对索引加锁 2.如果更新语句使用多个索引,行级锁会先锁定普通索引,再锁定聚簇索引 ...
- mysql 间隙锁专题
本文研究记录mysql间隙锁,涉及以下情况 唯一索引 非唯一索引 范围更新 等值更新 mysql8 mysql7 RR RC 数据准备 mysql> select * from vodb.tes ...
- Mysql 间隙锁原理,以及Repeatable Read隔离级别下可以防止幻读原理(百度)
Mysql知识实在太丰富了,前几天百度的面试官问我MySql在Repeatable Read下面是否会有幻读出现,我说按照事务的特性当然会有, 但是面试官却说 Mysql 在Repeatable Re ...
- 关于mysql 间隙锁
前段时间系统老是出现update死锁,很是纠结.经过排查发现是间隙锁!间隙锁是innodb中行锁的一种, 但是这种锁锁住的却不止一行数据,他锁住的是多行,是一个数据范围.间隙锁的主要作用是为了防止出现 ...
- MySQL间隙锁问题
间隙锁(Gap Lock):锁加在不存在的空闲空间,可以是两个索引记录之间,也可能是第一个索引记录之前或最后一个索引之后的空间. 最近用户反馈说系统老是出现insert时,等待超时了,最后发现是ins ...
- mysql间隙锁
什么是间隙锁(gap lock)? 间隙锁是一个在索引记录之间的间隙上的锁. 间隙锁的作用? 保证某个间隙内的数据在锁定情况下不会发生任何变化.比如我mysql默认隔离级别下的可重复读(RR). 当使 ...
- Mysql innodb 间隙锁
前段时间系统老是出现insert死锁,很是纠结.经过排查发现是间隙锁!间隙锁是innodb中行锁的一种, 但是这种锁锁住的却不止一行数据,他锁住的是多行,是一个数据范围.间隙锁的主要作用是为了防止出现 ...
- Mysql锁机制--间隙锁的危害
Mysql 系列文章主页 =============== 1 准备数据 1.1 建表 DROP TABLE IF EXISTS employee; CREATE TABLE IF NOT EXISTS ...
- Mysql加锁过程详解(9)-innodb下的记录锁,间隙锁,next-key锁
Mysql加锁过程详解(1)-基本知识 Mysql加锁过程详解(2)-关于mysql 幻读理解 Mysql加锁过程详解(3)-关于mysql 幻读理解 Mysql加锁过程详解(4)-select fo ...
随机推荐
- Linked List 单向链表
Linked List 链表的理解 小结 链表是以节点的方式来储存的 每个节点包括 data域:存放数据,next域:指向下一个节点 如图:发现链表的各个节点不一定是连续储存的 链表分为带头节点的链表 ...
- 服务器搭建远程docker深度学习环境
服务器搭建远程docker深度学习环境 本文大部分内容参考知乎文章 Docker+PyCharm快速搭建机器学习开发环境 搭建过程中出现ssh连接问题可以查看最后的注意事项 Docker Docker ...
- React 和 VUE 的区别和优缺点
前言 React 是由Facebook创建的JavaScript UI框架,React推广了 Virtual DOM( 虚拟 DOM )并创造了 JSX 语法.JSX 语法的出现允许我们在 javas ...
- LG P2389 电脑班的裁员
Description ZZY有独特的裁员技巧:每个同学都有一个考试得分$a_i(-1000 \leq a_i \leq 1000)$,在$n$个同学$(n \leq 500)$中选出不大于$k$段$ ...
- 使用GO实现Paxos分布式一致性协议
什么是Paxos分布式一致性协议 最初的服务往往都是通过单体架构对外提供的,即单Server-单Database模式.随着业务的不断扩展,用户和请求数都在不断上升,如何应对大量的请求就成了每个服务都需 ...
- cnblog维护
title: 博客归纳 blog: CSDN data: Java学习路线及视频 2019 12/31 时间管理 2020 1/22 Git是什么? 1/23 Git安装--Windows 3/24 ...
- netty之bootstrap
转载自https://blog.csdn.net/zxhoo/article/details/17419229 Netty4学习笔记(2)-- Bootstrap Netty4的代码比我想象的要复杂的 ...
- MySQL 10w+数据 insert 优化
由于业务原因,遇到了如题所述的业务问题,事务执行时间在30s~50s 不等,效果非常不理想 方案1. jdbc批处理 5w+ 数据测试,分别使用了mybatis insert()()(拼接xml) ...
- 【Flutter 实战】大量复杂数据持久化
老孟导读:上一篇文章讲解了 Android 和 iOS 的文件目录系统,此篇文章讲解如何使用 SQLite 保存数据. 欢迎大家投稿:http://laomengit.com/plan/Contrib ...
- 2019.8.14 sdfzoier
zhaojinxi wxk: lixf zhangtingyu wu jialin zhangjinhao liuxinyang zhoukaixuan