首页 > 数据库 >执行 delete from t1 where id = 10;MySQL会加什么锁?

执行 delete from t1 where id = 10;MySQL会加什么锁?

时间:2024-06-03 09:23:43浏览次数:30  
标签:10 加锁 记录 会加 id 索引 t1 主键

思考一个问题:下面一条简单的SQL,它加什么锁?

  • delete from t1 where id = 10;

带着你的答案,我们继续往下看。

如果要分析上述SQL的加锁情况,必须了解这个SQL的执行前提,MySQL的隔离级别是什么?id列是不是主键?id列有没有索引?前提不同加锁处理的方式也不同。

可能的情况:

  • id列是不是主键?
  • MySQL的隔离级别是什么?
  • id列如果不是主键,那么id列上有索引吗?
  • id列上如果有二级索引,那么这个索引是唯一索引吗?
  • SQL的执行计划是什么?索引扫描?全表扫描?

根据上述情况,有以下几种组合:

  • id列是主键,RC隔离级别
  • id列是二级唯一索引,RC隔离级别
  • id列是二级非唯一索引,RC隔离级别
  • id列上没有索引,RC隔离级别
  • id列是主键,RR隔离级别
  • id列是二级唯一索引,RR隔离级别
  • id列是二级非唯一索引,RR隔离级别
  • id列上没有索引,RR隔离级别

问题看起来变得复杂了,事实上,要分析加锁,就得考虑这么多情况,不过只要你选定了一种组合,SQL需要加哪些锁,其实也就确定了。

聊一聊几个比较经典的组合:

组合一:id主键+RC

大部分系统都是Read Committed隔离级别,id列是主键,这种情况只需要将主键上,id = 10的记录加上X锁即可。见下图:

 

 

结论:id是主键时,此SQL只需要在id=10这条记录上加X锁即可。

组合二:id唯一索引+RC

id是一个Unique的二级索引键值。那么在RC隔离级别下,delete from t1 where id = 10; 需要加什么锁呢?

见下图:

 

 

name列是主键,id列是唯一索引。此时,加锁的情况由于组合一有所不同。由于id是唯一索引,因此delete语句会选择走id列的索引进行where条件的过滤,在找到id=10的记录后,首先会将唯一索引上的id=10索引记录加上X锁,同时,会根据读取到的name列,回主键索引,然后将聚簇索引上的name = ‘d’ 对应的主键索引项加X锁。

结论:若id列上有唯一索引。那么SQL需要加两个X锁,一个对应于id唯一索引上的id = 10的记录,另一把锁对应于聚簇索引上的[name=’d’,id=10]的记录

组合三:id非唯一索引+RC

id列只有一个普通的索引,那么此时会持有哪些锁?

见下图:

 

 

首先,id列索引上,满足id = 10查询条件的记录,均已加锁。同时,这些记录对应的主键索引上的记录也都加上了锁。与组合二唯一的区别在于,组合二最多只有一个满足等值查询的记录,而组合三会将所有满足查询条件的记录都加锁。

结论:若id列上有非唯一索引,那么对应的所有满足SQL查询条件的记录,都会被加锁。同时,这些记录在主键索引上的记录,也会被加锁。

组合四:id无索引+RC

id列上没有索引,where id = 10;这个过滤条件,没法通过索引进行过滤,那么只能走全表扫描做过滤。对应于这个组合,SQL会加什么锁?

见下图:

 

 

由于id列上没有索引,因此只能走聚簇索引,进行全部扫描。从图中可以看到,满足删除条件的记录有两条,但是,聚簇索引上所有的记录,都被加上了X锁。无论记录是否满足条件,全部被加上X锁。既不是加表锁,也不是在满足条件的记录上加行锁。有人可能会问?为什么不是只在满足条件的记录上加锁呢?这是由于MySQL的实现决定的。如果一个条件无法通过索引快速过滤,那么存储引擎层面就会将所有记录加锁后返回,然后由MySQL Server层进行过滤。因此也就把所有的记录,都锁上了。

结论:若id列上没有索引,SQL会走聚簇索引的全扫描进行过滤,由于过滤是由MySQL Server层面进行的。因此每条记录,无论是否满足条件,都会被加上X锁。但是,为了效率考量,MySQL做了优化,对于不满足条件的记录,会在判断后放锁,最终持有的,是满足条件的记录上的锁,但是不满足条件的记录上的加锁/放锁动作不会省略。同时,优化也违背了2PL的约束。

面的四个组合,都是在Read Committed隔离级别下的加锁行为,接下来的四个组合,是在Repeatable Read隔离级别下的加锁行为。

组合五:id主键+RR

id列是主键列,Repeatable Read隔离级别,针对delete from t1 where id = 10; 这条SQL,加锁与组合一:[id主键,Read Committed]一致。

组合六:id唯一索引+RR

组合六的加锁,与组合二:[id唯一索引,Read Committed]一致。两个X锁,id唯一索引满足条件的记录上一个,对应的聚簇索引上的记录一个。

组合七:id非唯一索引+RR

在RR隔离级别下,为了防止幻读的发生,会使用Gap锁。这里,你可以把Gap锁理解为,不允许在数据记录前面插入数据。对应于这个组合,SQL会加什么锁?

见下图:

 

 


结论:Repeatable Read隔离级别下,id列上有一个非唯一索引,对应SQL:delete from t1 where id = 10; 首先,通过id索引定位到第一条满足查询条件的记录,加记录上的X锁,加GAP上的GAP锁,然后加主键聚簇索引上的记录X锁,然后返回;然后读取下一条,重复进行。直至进行到第一条不满足条件的记录[11,f],此时,不需要加记录X锁,但是仍旧需要加GAP锁,最后返回结束。什么时候会取得gap lock或nextkey lock 这和隔离级别有关,只在REPEATABLE READ或以上的隔离级别下的特定操作才会取得gap lock或nextkey lock。

组合八:id无索引+RR

Repeatable Read隔离级别下的最后一种情况,id列上没有索引。此时SQL:delete from t1 where id = 10; 没有其他的路径可以选择,只能进行全表扫描。最终的加锁情况,见下图:

 

结论:在Repeatable Read隔离级别下,如果进行全表扫描的当前读,那么会锁上表中的所有记录,同时会锁上聚簇索引内的所有GAP,杜绝所有的并发 更新/删除/插入 操作。当然,也可以通过触发semi-consistent read,来缓解加锁开销与并发影响,但是semi-consistent read本身也会带来其他问题,不建议使用。

总结

本文对MySQL一些基础性的知识点进行了详细的总结,参考了网上和书上比较多的资料和实例。希望能对各位的学习有所帮助。

标签:10,加锁,记录,会加,id,索引,t1,主键
From: https://www.cnblogs.com/shujuyr/p/18228038

相关文章

  • 基于STM32F103C8T6微控制器的物流信息检测系统
    摘要本论文设计并实现了一种基于STM32F103C8T6微控制器的物流信息检测系统。该系统旨在通过综合各种传感器模块实现对运输车环境及状态的实时监控,并通过4G网络将信息发送到手机端,以便用户进行远程管理和控制。首先,系统通过GPS模块获取运输车的位置信息,实现车辆定位和轨迹跟踪......
  • win10将批处理文件(xxx.bat)固定到开始屏幕或任务栏
    参考链接:https://blog.csdn.net/weixin_42529699/article/details/1009214731、任意位置【右键】-【新建】-【快捷方式】 2、在“请键入对象的位置”下的输入框中按以下格式输入bat文件的路径cmd/c“批处理文件路径”:批处理文件执行完后窗口自动关闭;cmd/k“批处理文件......
  • Shell阶段10 awk工作原理, 内部变量, 正则/比较/条件/逻辑表达式, 判断语句, 循环语
    AWK什么是awkawk是一个编程语言主要作用:对文本和数据的处理awk处理数据的流程1.扫描文件内容,从上到下进行扫描,按照行进行处理2.寻找匹配到的内容,进行读取到特定的模式中,进行行处理3.行满足指定模式动作,则输出到屏幕上面,不满足丢弃4.接着读取下一行继续处理,接着循环,直......
  • Windows10系统中安装与配置PyTorch(无GPU版本)
    文章目录1.什么是PyTorch2.PyTorch的安装与配置(无GPU)2.1创建环境2.2安装pytorch库(无GPU)2.3验证安装结果1.什么是PyTorchPyTorch是一种用于构建深度学习模型且功能完备的开源框架,通常用于处理图像识别和语言处理等应用当中的机器学习。PyTorch保留了Torch(L......
  • F1000 Research 准备研究文章
    准备研究文章  LINK  本页提供有关为F1000Research撰写研究文章的信息,包括文章中必须包含的关键部分。另请参阅F1000Research的编辑政策。此处提供了研究文章的模板。标准研究文章应呈现发现和见解的独创性,并为各自的研究领域提供理论、实证、实验和/或方法论的进步。还......
  • 100311. 无需开会的工作日
    题目描述给你一个正整数days,表示员工可工作的总天数(从第1天开始)。另给你一个二维数组meetings,长度为n,其中meetings[i]=[start_i,end_i]表示第i次会议的开始和结束天数(包含首尾)。返回员工可工作且没有安排会议的天数。注意:会议时间可能会有重叠。情况描述6月2日周......
  • # window10 设置一个【自定义运行】命令行快捷方式
    window10设置一个【自定义运行】命令行快捷方式window10[运行】命令行打不开,可采用如下简单快捷方法:1、右键点击桌面空白处,然后点击【新建】,再点击【快捷方式】。2、在【请键入对象的位置】文本框输入:explorershell:::{2559a1f3-21d7-11d4-bdaf-00c04f60b9f0}3......
  • # WIN10/WIN11 找不到【应用商店 Microsoft.WindowsStore】怎么办?
    WIN10/WIN11找不到【应用商店Microsoft.WindowsStore】怎么办?解决方法:1、右键【开始】菜单,点击【WindowsPowerShell(管理员)】,输入:Get-AppxPackage-allusers|SelectName,PackageFullName2、查询到的目录中找到【Microsoft.WindowsStore】,复制后面的可安装版本......
  • 解读10个高考填志愿你必须知道的名词(附:高考志愿填报指导音频)
    大家好,今天我们就来和大家解读一下十个填志愿你必须知道的名词。第一个名词:录取批次录取批次是指根据不同高校情况所划分的录取顺序录取步骤。分为本科一批次,本科二批次,专科提前批次,高职批次,需要注意的是,录取批次具有严格的顺序性。上一批次未录取完毕,不得进行下一批次的录......
  • TCP_FLAGS_INVALID_10: [finwait-2] (otw SEQ)-> ACK(seq) [finwait-2]
    测试目的:验证TCP在FINWAIT-2状态下,接收到一个序列号超出窗口(OTW)的段时,是否能够发送一个ACK段,并保持在相同的状态。描述:TCP在FINWAIT-2状态下,如果接收到一个没有RST标志且序列号超出接收窗口的段,它必须发送一个ACK段,其中确认号表示期望的下一个序列号,并保持在FINWAIT-2状......