【数据库】间隙锁Gap Lock

什么是间隙锁

间隙锁(Gap Lock):间隙锁是(RR级别下)一个在索引记录之间的间隙上的锁,可以是两个索引记录之间,也可能是第一个索引记录之前或最后一个索引之后的空间。间隙锁(Gap Lock)是Innodb在可重复读提交下为了解决幻读问题时引入的锁机制
当我们用范围条件而不是相等条件索引数据,并请求共享或排他锁时,InnoDB会给符合条件的已有数据记录的索引项加锁;对于键值在条件范围内但并不存在的记录,叫做“间隙(GAP)”。InnoDB也会对这个“间隙”加锁,它锁住的是多行,是一个数据范围,这种锁机制就是所谓的间隙锁(Next-Key锁)。
在这里插入图片描述

间隙锁的危害

因为Query执行过程中通过范围查找的话,他会锁定整个范围内所有的索引键值,即使这个键值并不存在。间隙锁有一个比较致命的弱点,就是当锁定一个范围键值之后,即使某些不存在的键值也会被无辜的锁定,也造成在锁定的时候无法插入锁定键值范围内的任何数据。在某些场景下这可能会对性能造成很大的危害。

间隙锁与死锁

最近用户反馈说系统老是出现insert时,等待超时了,最后发现是insert间隙锁!间隙锁是innodb中行锁的一种, 但是这种锁锁住的却不止一行数据,他锁住的是多行,是一个数据范围。间隙锁的主要作用是为了防止出现幻读,但是它会把锁定范围扩大,

有时候也会给我们带来麻烦,我们就遇到了。 在数据库参数中, 控制间隙锁的参数是:innodb_locks_unsafe_for_binlog

这个参数默认值是OFF, 也就是启用间隙锁, 他是一个bool值, 当值为true时表示disable间隙锁。

那为了防止间隙锁是不是直接将innodb_locaks_unsafe_for_binlog设置为true就可以了呢? 不一定!

而且这个参数会影响到主从复制及灾难恢复, 这个方法还尚待商量。

很容易产生间隙锁的位置

间隙锁的出现主要集中在同一个事务中先delete后 insert的情况下, 当我们通过一个参数去删除一条记录的时候,

如果参数在数据库中存在,那么这个时候产生的是普通行锁,锁住这个记录, 然后删除, 然后释放锁。
如果这条记录不存在,就有问题了, 数据库会扫描索引,发现这个记录不存在, 这个时候的delete语句获取到的就是一个间隙锁,然后数据库会向左扫描扫到第一个比给定参数小的值,向右扫描扫描到第一个比给定参数大的值, 然后以此为界,构建一个区间, 锁住整个区间内的数据, 一个特别容易出现死锁的间隙锁诞生了。间隙锁加锁是非互斥的,AB都删除同一个不同在的数据,产生了两个一样的互斥锁,然后都去插入数据,这时候他们都只能拿到自己的间隙锁,拿不到另外一个间隙锁,就进入了互相等待的死锁环节。
image-20220113020411432

间隙锁产生的原因或者说作用

间隙锁的出现是为了在innodb的可重复读隔离级别下,解决幻读问题产生的。

间隙锁会封锁该条记录相邻两个键之间的空白区域,防止其它事务在这个区域内插入、修改、删除数据;所谓间隙是将数据分为不同区间,对该区间范围进行加锁,区间的规则为左开右闭,比如当数据为1,3,5时,对应的区间为(-∞,1],(1,3],(3,5],(5,+∞];

他这个行锁+间隙锁就组成了next—key lock,innodb在可重复度隔离级别下,采用next-key lock来防止幻读,因此实现了最高的隔离级别。

可能产生间隙锁的位置

对于操作的数据是主键索引和普通索引,有不同的加锁规则,如下:

1)、唯一索引只有锁住多条记录或者一条不存在的记录的时候,才会产生间隙锁,指定给某条存在的记录加锁的时候,只会加记录锁,不会产生间隙锁;
2)、普通索引不管是锁住单条,还是多条记录,都会产生间隙锁;

解决方案

①降低事务级别至读已提交(不推荐)

②先判断有无数据,有数据删,无数据则不删,因为删除不存在的数据一定会加间隙锁

③间隙锁非互斥锁,只针对写锁,只要两个线程锁定的区间有交叉就会出现死锁。可以根据条件查出所有主键,根据主键删除数据,这样只会加行锁而不是间隙锁(推荐)

④你如果把隔离级别设置为读提交的话,就没有间隙锁了。但同时,你要解决可能出现的数据和日志不一致问题,需要把 binlog 格式设置为 row。如果读提交隔离级别够用,也就是说,业务不需要可重复读的保证,这样考虑到读提交下操作数据的锁范围更小(没有间隙锁),这个选择是合理的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/321164.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【数据结构与算法】之数组系列-20240115

这里写目录标题 一、599. 两个列表的最小索引总和二、724. 寻找数组的中心下标三、面试题 16.11. 跳水板四、35. 搜索插入位置 一、599. 两个列表的最小索引总和 简单 假设 Andy 和 Doris 想在晚餐时选择一家餐厅,并且他们都有一个表示最喜爱餐厅的列表&#xff0c…

vue项目之.env文件.env.dev、test、pro

.env文件是vue运行项目时的环境配置文件。 .env: 全局默认配置文件,所有环境(开发、测试、生产等)均会加载并合并该文件 .env.development(开发环境默认命名) 开发环境的配置,文件名默认为.env.development,如果需要改名也是可以的&#xf…

记录误删除docker中极狐gitlab容器恢复过程

如题一次误操作导致删除了docker中极狐gitlab容器恢复过程 情况说明 创建容器时,我是用的是极狐官网推荐安装的步骤,具体按照官网步骤走就行 sudo docker run --detach \--hostname gitlab.example.com \--publish 443:443 --publish 80:80 --publish …

steam搬砖项目赚钱吗?低门槛副业月入5k真的假的?

steam搬砖项目一开始默默无闻,现在越来越受欢迎,因为大家都看到了该项目的长期稳定性。 steam搬砖项目主要是搬csgo游戏装备和道具,从steam购买,在网易Buff上出售,赚取差价。只需少量投资,即可获得长期稳定…

港大谷歌提出GO-NeRF:在NeRF中生成协调且高质量的3D对象

尽管在3D生成方面取得了进展,但在作为NeRF表示的现有3D场景中直接创建3D对象仍然是未经探索的。这个过程不仅需要高质量的3D对象生成,还需要将生成的3D内容无缝地合成到现有的NeRF中。为此,作者提出了一种新方法,GO-NeRF&#xff…

C++深入学习之STL:1、容器部分

标准模板库STL的组成 主要由六大基本组件组成:容器、迭代器、算法、适配器、函数对象(仿函数)以及空间配置器。 容器:就是用来存数据的,也称为数据结构。 本文要详述的是容器主要如下: 序列式容器:vector、list 关联…

AC修炼计划(AtCoder Beginner Contest 335)E-F

传送门: AtCoder Beginner Contest 335 (Sponsored by Mynavi) - AtCoder A,B,C,D还算比较基础,没有什么思路,纯暴力就可以过。 这里来总结一下E和F E - Non-Decreasing Colorful Path 最开始以为是树形…

顶级Web应用程序测试工具列表

今天主要列举Web应用程序的工具。 今天的列表仅仅提供索引功能,具体要使用的同学,可以自行搜索哦。 通过web应用程序测试,在web应用程序公开发布之前,会发现网站功能、安全性、可访问性、可用性、兼容性和性能等问题。 Web应用程…

细说JavaScript语句详解

一、顺序结构 二、表达式语句 三、声明语句 四、条件语句 1、if语句 2、if…else语句 3、else if语句 4、switch语句 五、循环语句 1、while循环 2、do… while循环 3、for循环 4、for…in循环 六、跳出语句 1、label语句 2、break语句 3、continue语句

【MySQL】基础篇

文章目录 一、SQL规则与规范二、基本的SELECT语句SELECT...FROM...;列的别名 AS ""去除重复行 DISTINCT空值参与运算 结果一定也为NULL着重号 常量描述表结构 DESCRIBE过滤数据 WHERE 三、运算符算术运算符比较运算符非符号类型运算符逻辑运算符运算符优先级 四、排序…

Git 是什么?

Git 是什么? Git 是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。 Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。 Git 与常用的版本控制工具 CVS, Subversion 等不同,…

ubuntu 2022.04 安装vcs2018和verdi2018

主要参考网站朋友们的作业。 安装时参考: ubuntu18.04安装vcs、verdi2018_ubuntu安装vcs-CSDN博客https://blog.csdn.net/qq_24287711/article/details/130017583 编译时参考: 【ASIC】VCS报Error-[VCS_COM_UNE] Cannot find VCS compiler解决方法_e…

陶瓷碗口缺口检测-图像分割

图像分割 由于对碗口进行缺口检测,因此只需要碗口的边界信息。得到陶瓷碗区域填充后的图像,对图像进行边缘检测。这是属于图像分割中的内容,在图像的边缘中,可以利用导数算子对数字图像求差分,将边缘提取出来。 本案…

电流检测方法

电路检测电路常用于:高压短路保护、电机控制、DC/DC换流器、系统功耗管理、二次电池的电流管理、蓄电池管理等电流检测等场景。 对于大部分应用,都是通过感测电阻两端的压降测量电流。 一般使用电流通过时的压降为数十mV~数百mV的电阻值&…

42 智能指针 auto_ptr, unique_ptr,shared_ptr,weak_ptr 整理

都是类模版 都不用开发者自己delete 指针。这是因为智能指针有自己管理指向对象的能力,包括释放指向的内存,因此开发者不要自己释放。 auto_ptr, (废弃)C98 已经被弃用,替代方案是unique_ptr. 被弃用的原因: 1.不能…

基于传统机器学习模型算法的项目开发详细过程

1 场景分析 1.1 项目背景 描述开发项目模型的一系列情境和因素,包括问题、需求、机会、市场环境、竞争情况等 1.2. 解决问题 传统机器学习在解决实际问题中主要分为两类: 有监督学习:已知输入、输出之间的关系而进行的学习,从而…

Minio安装及整合SpringBoot

一. MinIO概述 官网地址:https://minio.org.cn MinIO是一款基于Apache License v2.0开源协议的分布式文件系统(或者叫对象存储服务),可以做为云存储的解决方案用来保存海量的图片、视频、文档等。由于采用Golang实现,服…

《Git学习笔记:Git入门 常用命令》

1. Git概述 1.1 什么是Git? Git是一个分布式版本控制工具,主要用于管理开发过程中的源代码文件(Java类、xml文件、html页面等),在软件开发过程中被广泛使用。 其它的版本控制工具 SVNCVSVSS 1.2 学完Git之后能做…

数据在AI任务中的决定性作用:以图像分类为例

人工智能的学习之路非常漫长,不少人因为学习路线不对或者学习内容不够专业而举步难行。不过别担心,我为大家整理了一份600多G的学习资源,基本上涵盖了人工智能学习的所有内容。点击下方链接,0元进群领取学习资源,让你的学习之路更加顺畅!记得…

基于SSM的法律咨询系统的设计与实现

末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:Vue 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目:是 目录…