【Mysql】next-key 锁范围

news2024/11/18 10:32:30

背景

Mysql RR场景下通过next-key 锁解决了幻读的问题,而幻读通常是由 insert 新增的数据导致。所以next-key锁最终通过锁机制防止了一定条件下的新增数据从而解决了幻读问题。

规律

next-key锁可以由以下几条规律总结出锁范围

  • next-key会对查询过程中访问到的对象进行加锁
  • next-key锁通常是左开右闭的
  • 在唯一索引上做等值查询时,next-key锁会退化成行锁
  • 在做等值查询时,查询最后访问到的一个对象所加的next-key上不包含右节点,也就是变成了两边都是开区间
  • 在唯一索引上做范围查询时,会访问到下一个不满足条件的对象上(Mysql 5.7版本)

实例

表数据结构
id 列是主键,c列上有普通索引,表内数据如下

idcd
000
555
101010
151515
202020
252525

等值查询间隙锁

在这里插入图片描述
第一个 update 语句会先找 id = 7 的数据,所以在 主键索引上的 B+树上做查询时,会先扫描 id = 7 的这一行,但是表内没有这一条数据,所以找到了比他大的第一条数据,也就是 id = 10 这一行。
再根据next-key加锁规律进行加锁,先加一个左开右闭的锁,再因为做等值查询时,最后不满足条件的第一条数据变成左开右开区间,从而给 (5, 10) 这一个范围加上了锁。
最终导致 insert 8 插入失败,update 10 更新成功。

非唯一索引等值锁

在这里插入图片描述
第一个 select … … lock in share mode 会先在索引树上找到 c = 5, id = 5 这一行,因为不知道有其他的 c = 5,会继续向下找,找到 c = 10, id = 10 这一行并终止查询。
所以根据规律,会现在索引 c 上加 (0, 5] 和 (5, 10] 上加锁,并因为做等值查询,将范围改为 (0, 5] 和 (5, 10)。
在做 update id = 5 这一行数据时,因为 修改对象是 id = 5 不在 索引 c 上,所以修改成功。
而做 insert c = 7 时,因为在锁区间内,所以 插入失败。
在这里不对 主键 索引 id 上加锁,是因为 select id … lock in share mode 的特殊性,首先因为覆盖索引的特殊性, id 列本身就在 索引 c 的B+树叶子节点上,所以不涉及到回表,访问到的对象也只有 索引 c 上的树节点。

如果将 lock in share mode 换成 for update。此时,update 就会被 block 住,因为 Mysql 会认为这将会造成一条更新,所以会将锁向 主键索引传递,为对应的主键索引数据行加锁。

主键索引范围锁

在这里插入图片描述

第一个 select 语言会扫描所有 id >= 10 并且 id < 11 的 主键索引数据行,所以会先找到 id = 10 这一行,并且接着向下扫描扫描到 id = 15 这一行时,不满足条件,结束查询。
所以根据规律会先对(5, 10] 和 (10,15] 上加锁,因为唯一索引加等值查询的原因,第一个next-key锁退化为行锁,最终变成[10,15] 这个范围。
从而导致 insert 8 成功,insert 13 失败,update 15 失败。

非唯一索引范围锁

在这里插入图片描述
第一个 select 语言会扫描所有 c >= 10 并且 c < 11 的 主键索引数据行,所以会先找到 c = 10 这一行,并且接着向下扫描扫描到 c = 15 这一行时,不满足条件,结束查询。
所以根据规律会先对(5, 10] 和 (10,15] 上加锁。

这里和上面不同,首先是因为 做 c>= 10 时,索引 c 不是唯一索引,所以不会退化为行锁
其次在做 c < 11 时,不是 等值查询,所以也不用做 左开右开的退化。

唯一索引范围锁 bug

在这里插入图片描述
这个查询会扫描所有 id > 10 并且 id <= 15 的 主键索引数据行,所以会先找到比10大的第一行 也就是 id = 15 这一行,并且接着向下扫描扫描到 id = 15 这一行时,正常会因为 唯一索引的原因,不会存在 第二个 id = 15 了,但是因为规律第五条的原因会继续向下扫描到 id = 20 这一行,结束查询。
所以最终加锁范围是 (10,15] 和 (15, 20] 这两个区间。
导致 update 20 修改失败, insert 16 插入失败。

非唯一索引上存在"等值"的例子

此时,数据表中多一条 (30, 10, 30)的数据,此时数据表中数据为

idcd
000
555
101010
151515
202020
252525
301030

在这里插入图片描述

因为第一条 delete c = 10 ,会先扫描 索引 c 的 B+树上 c = 10 的数据行,接着因为 c 不是唯一索引,不知道 有没有其他的 c = 10 会继续向下扫描,知道扫描到 c = 15 时,不满足条件,结束查询。
此时,根据next - key 规律,会先加 (5, 10] 和 (10, 15] 锁,并因为等值查询的原因,第二段锁退化成左开右开,变成 (5, 10] 和 (10, 15) 锁区间。
最终导致 insert 12 插入失败,update 15 更新成功。

limit 语句加锁

此时,数据表中多一条 (30, 10, 30)的数据,此时数据表中数据为

idcd
000
555
101010
151515
202020
252525
301030

在这里插入图片描述
因为第一条 delete c = 10 ,会先扫描 索引 c 的 B+树上 c = 10 的数据行,也就是 c = 10, id = 10 和 c = 10, id = 30 这两条,此时因为 limit 2 的原因,扫描到这两条之后满足条件就退出查询了,不会继续向下扫描 c = 15 这一行。

所以加锁范围就仅仅是 (5, 10] 这一个区间了。
最终导致 insert 12 插入成功。

一个死锁的例子

在这里插入图片描述
next-key 锁由间隙锁(左开右开) 和 行锁组成,所以在某些情况下会出现 间隙锁加锁成功,行锁加锁失败的场景。
在这段语句中,Session A 做 select lock in share mode时,会对(5,10] 加锁,并且因为 share mode的原因是共享锁。

在做update c = 10 最终结果失败的,但是由于间隙锁和行锁的原因,Session B 的间隙锁加锁成功,c = 10 的行锁加锁失败。

Session A 此时又要插入 8,这个 8 在 Session B 的间隙锁区间内,所以也加锁失败,开始等待。

这个时候Session A 在等待 Session B 释放锁,Session B 又在等待 Session A 释放锁,构成死锁条件。

参考

Mysql 实战45讲 20节
Mysql 实战45讲 21节

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

灵活用工仿boss直聘招聘系统劳务系统源码

灵活用工仿boss直聘招聘系统劳务系统 开发语言&#xff1a; 后台&#xff1a;phpmysql&#xff0c;fastadmin框架 前端&#xff1a;vue&#xff0c;Uniapp 功能介绍&#xff1a; 1.登录 账号密码登录&#xff0c;微信手机号授权登录 2.首页&#xff1a;定位功能&#xf…

前端和空字符串、零比较时请务必使用===

在前端开发中遇到一个问题&#xff0c;以下两条语句的结果都是true。 console.log(0 ""); console.log(false ""); 这就导致了editingId为0的时候&#xff0c;if分支并没有执行&#xff0c;而我的本意是当editingId不是空也不是空字符串的时候执行分支…

实战Leetcode(三)

Practice makes perfect&#xff01; 实战一&#xff1a; 带环问题其实我们小学时就接触过&#xff0c;就比如在操场上比赛跑步的追击问题&#xff0c;这里也是一样&#xff0c;如果我们定义两个指针&#xff0c;一个快指针&#xff0c;一个慢指针&#xff0c;快指针走的快&…

SQL 算数函数

AVG() 求数值列的平均值。 具体计算过程&#xff1a;其通过对表中行数计数并计算特定数值列的列值之和&#xff0c;求得该列的平均值。 语法&#xff1a; SELECT AVG(column_name) FROM table_name; 当参数 column_name 列中的数据均为空时&#xff0c;结果会返回 NULL。 …

python实现炒股自动化,个人账户无门槛量化交易的开始

本篇作为系列教程的引子&#xff0c;对股票量化程序化自动交易感兴趣的朋友可以关注我&#xff0c;现在只是个粗略计划&#xff0c;后续会根据需要重新调整&#xff0c;并陆续添加内容。 股票量化程序化自动交易接口 很多人在找股票个人账户实现程序化自动交易的接口&#xff0…

94.二叉树的中序遍历

描述 : 给定一个二叉树的根节点 root &#xff0c;返回 它的 中序 遍历 。 题目 : LeetCode 94.二叉树的中序遍历 : 94. 二叉树的中序遍历 分析 : 这个代码还是很好写的 ...... 解析 : /*** Definition for a binary tree node.* public class TreeNode {* int val;…

智汇云舟荣获2023轨道交通国际创新创业大赛“最具市场前景奖”

11月9日&#xff0c;由北京市科学技术委员会、中关村科技园区管理委员会、北京市经济和信息化局、北京市丰台区人民政府、中关村发展集团股份有限公司主办的2023中关村轨道交通国际创新创业大赛总决赛圆满收官。 智汇云舟提报的《视频孪生 改变视界》项目在数百个参赛项目中脱…

艾默生Emerson EDI需求分析

艾默生Emerson是一家全球领先的工程技术和解决方案提供商。该公司总部位于美国&#xff0c;成立于1890年&#xff0c;经过多年的发展&#xff0c;已经发展成为一个多元化的跨国企业&#xff0c;业务遍及工业、商业和消费者市场。艾默生提供各种产品和服务&#xff0c;包括自动化…

分销cps外卖券电影票小程序开发

电影票外卖劵分销CPS小程序开发作 我们致力于为消费者提供优质、便捷的外卖服务。现在&#xff0c;我们推出全新的电影票外卖劵分销CPS小程序&#xff0c;以及更多具有深度和专业度的功能和服务&#xff0c;以满足消费者更高的生活服务需求。 首先&#xff0c;我们的分销模式…

Spring Boot(二)

1、运行维护 1.1、打包程序 SpringBoot程序是基于Maven创建的&#xff0c;在Maven中提供有打包的指令&#xff0c;叫做package。本操作可以在Idea环境下执行。 mvn package 打包后会产生一个与工程名类似的jar文件&#xff0c;其名称是由模块名版本号.jar组成的。 1.2、程序…

苹果官方:所有国行iPhone 15系列都在中国生产!

近几年来&#xff0c;国内供应链逐渐外迁&#xff0c;而拥有庞大劳动力市场的印度却成为了香饽饽&#xff0c;逐渐获得越来越多企业的重视&#xff0c;就连苹果公司也将其视为发展的重要战略要地。 自从苹果扩大印度生产iPhone规模后&#xff0c;很快流言四起&#xff0c;各种负…

Redis(12)| 过期删除策略和内存淘汰策略

Redis 是可以对 key 设置过期时间的&#xff0c;因此需要有相应的机制将已过期的键值对删除&#xff0c;而做这个工作的就是过期键值删除策略。 如何设置过期时间 先说一下对 key 设置过期时间的命令。 设置 key 过期时间的命令一共有 4 个&#xff1a; expire key n&#x…

css:两个行内块元素和图片垂直居中对齐

目录 两个行内块元素垂直居中对齐图片垂直居中问题图片和文字垂直居中对齐参考文章 两个行内块元素垂直居中对齐 先看一段代码&#xff1a; <style> .box {width: 200px;height: 200px;line-height: 200px;font-size: 20px;text-align: center;display: inline-block;b…

外接式网络隔离变压器/网络隔离滤波器/网口变压器/脉冲变压器/网络隔离变压器模块

Hqst华强盛&#xff08;石门盈盛&#xff09;电子导读&#xff1a;外接式网络隔离变压器/网络隔离滤波器/网口变压器/脉冲变压器/网络隔离变压器模块&#xff0c;后统称网络隔离变压器&#xff0c;它是一种安装在电路外部的隔离变压器&#xff0c;主要用于隔离网络中的干扰信号…

动态规划(4)---Leetcode.746使用最小花费爬楼梯

题目 给你一个整数数组 cost &#xff0c;其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用&#xff0c;即可选择向上爬一个或者两个台阶。 你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。 请你计算并返回达到楼梯顶部的最低花费。 思路 建…

基于ubuntu22.04手动安装openstack——2023.2版本(最新版)的问题汇总

前言&#xff1a;基本上按照openstack官方网站动手可以搭建成功&#xff08;如有需要私信发部署文档&#xff09;。 但是任然有些小问题&#xff0c;所以汇总如下。 第一个问题 问题&#xff1a; ubuntu搭建2023.2版本neutorn报错&#xff0c;ERROR neutron.plugins.ml2.driv…

【已验证-直接用】微信小程序wx.request请求服务器json数据并渲染到页面

微信小程序的数据总不能写死吧&#xff0c;肯定是要结合数据库来做数据更新&#xff0c;而小程序数据主要是json数据格式&#xff0c;所以我们可以利用php操作数据库&#xff0c;把数据以json格式数据输出即可。 现在给大家讲一下微信小程序的wx.request请求服务器获取数据的用…

计算机组成原理之处理器(单周期)

引言 处理器的实现方式决定了时钟周期长度和CPI。实现方式有单周期与流水线&#xff0c;本篇谈谈单周期处理器。 目前CPU的频率一般是3GHZ/4GHZ&#xff0c;但是频率是有极限值的&#xff0c;受cycletime影响 基本的RISC-V实现 存储指令&#xff1a;ld,sd算术逻辑指令 &…

【图文详解】Android Studio(新版本) 配置OpenCV库,解决出现的各种问题

前言 写这篇文章的目的就是记录自己在配置OpenCV库时遇到的问题。在网上查找相关资料时&#xff0c;发现很多Android Studio都是老版本&#xff0c;并且出现的问题都不能被解决。自己在配置过程中出现的问题都进行记录下来并一一解决。 新建项目 点击 New Project 选择界面 …

什么工具可以制作照片书并分享到微信?

大家平时在微信朋友圈&#xff0c;有没有看到别人发的翻页效果的照片书&#xff1f;这种照片书&#xff0c;通过链接或者二维码就能够在线观看&#xff0c;仿真翻页效果&#xff0c;就跟真实的看纸质相册一样&#xff0c;阅读体验感真的是超级nice&#xff01; 那你们知道这种…