秋招——MySQL补充——MySQL是如何加行级锁

文章目录

    • 引言
    • 正文
      • 什么SQL语句会加行级锁
        • 查询操作增加对应的行级锁
          • 事务的写法
        • update和delete修改操作也会增加行级锁
      • 行级锁有哪些种类
        • 记录锁
        • 间隙锁
        • Next-Key锁
      • MySQL是如何加行级锁?
        • 唯一索引等值查询
          • 查询记录是存在的
          • 查询记录是不存在的
        • 唯一索引范围查找
          • 针对大于或者大于等于的范围查询
          • 针对小于等于的范围查询
        • 非唯一索引等值查询
          • 记录不存的情况
          • 记录存在的时候
        • 非唯一 索引范围查询
        • 没有加索引的查询
    • 总结

引言

  • 在做一些SQL的过程中,总是对于行级锁会出现的一些理解上的问题,就找了一些资料,来补充一下,之前只不过是背过了,但是并不深刻理解。
  • 这里参考的都是小林coding的内容,链接
  • 这里是看了小林coding的内容,然后自己在进行二次消化总结,目录结构基本上是一致的。

正文

什么SQL语句会加行级锁

  • 普通的select语句不加行级锁,快照读,通过MVCC来实现的。

  • 两种类型的锁,分别是共享锁和独占锁

在这里插入图片描述

  • 共享锁S:满足读读共享,读写互斥。
  • 独占锁X:满足写写互斥,读写互斥。
查询操作增加对应的行级锁

查询加锁的方式有两种,枷锁的查询语句成为锁定读

S型锁

select ... lock in share mode;

X型锁

select ... for update;

注意

  • 加锁的读语句,必须要在一个事务中,因为事务结束了就会自动释放锁。
事务的写法

事务的书写方式!!!这里个东西吧,拼多多就问了,就是会问你实操!

使用start transaction

START TRANSACTION;  // 开启一个新事物
//..///不同的SQL语句

selet * from table_a where id = 1 for update;

COMMIT;// 最后事务要提交

使用begin实现事务

Begin;  // 开启一个新事物
//..///不同的SQL语句

selet * from table_a where id = 1 for update;

COMMIT;// 最后事务要提交
update和delete修改操作也会增加行级锁
  • 删除和修改操作增加的都是独占型锁X型锁
update table colA = x where id = 1;
delete from table where id = 1;

行级锁有哪些种类

  • 记录锁Record Lock

    • 紧紧锁住一条记录
  • 间隙锁Gap Lock

    • 锁定一个范围,但是不包含记录本身
  • Next-key锁

    • 记录锁和间隙锁的组合,锁定一个范围并且锁定记录本身。

不同隔离级别下,锁是不同的

  • 读已提交的情况下,是记录锁
  • 可重复读的情况下,是记录锁和间隙锁(防止幻读)
记录锁
  • 记录锁,同时有共享锁和独占锁,需要自己指定。
  • 默认是独占锁,所以不能对这条记录进行任何操作
begin;
select * from table where condition for update;
commit;
间隙锁
  • 用于可重复读隔离级别,是解决幻读问题。

  • 在一定范围内,不再插入其他的数据

  • 间隙锁之间是相互兼容的

  • 不包含自身

Next-Key锁
  • 是记录锁和间隙锁的结合体,锁住一个范围的同时,还锁住了自身。
  • 保护该记录,并且组织其他事务将新纪录插入到被保护的记录前面的间隙中。

不同Next-Key锁之间是互不兼容的

MySQL是如何加行级锁?

  • 加锁的对象是索引,加锁的基本单位是next-key锁,
  • 但是在能够使用记录锁或者间隙锁就能避免幻读的场景
    • next-key锁会退化为记录锁和间隙锁

加锁的对象是针对索引的!!!

唯一索引等值查询
  • 使用唯一索引,进行等值查询的时候,按照查询记录是否存在,将锁退化为两种不同的形态
查询记录是存在的
  • 索引树上定位到这条记录后,将记录中的next-key退化为记录锁

陷入阻塞

在这里插入图片描述
在这里插入图片描述

退化为记录锁的原因

  • 主键具有唯一性,插入一个同主键的key-value,不满足唯一性约束。
  • 加了记录锁,就无法删除该纪录。
查询记录是不存在的
  • 在查询树上找到第一条大于该查询记录的记录后,将该记录中的next-key锁退化为间隙锁。

在这里插入图片描述
确定间隙锁的范围

  • 大于当前搜索的id的最接近的一个值,以当前值右边界,然后前一个值就是左边界。
  • 在唯一索引等值擦查询并且记录不存在的情况下,在索引树找到第一条大于该查询记录的记录后,将该记录的索引next-key退化为间隙锁

使用间隙锁,保证右边界不会被锁,在限定范围内就可以保证不出现幻读

唯一索引范围查找

唯一索引范围查找过程

  • 会对每一个扫描到的索引,加上next-key锁,然后如果遇到下述情况,会退化成记录锁或者间隙锁。
针对大于或者大于等于的范围查询

大于的情况

  • 对两个不同的区域加上next-key锁,限定访问范围
    • 第一个匹配的主键索引上,增加(edge,value]的范围锁,限定在这个范围内不在增加新的数据。
    • 对于最后一个特殊暴击的主键的索引上,就增加一个(value,+∞】主键索引,限定在这个范围内,不在增加的新的数据。
      在这里插入图片描述

大于等于的情况

  • 在等值索引匹配上,增加了一个记录锁,限定当前的值不被修改。其余都是相同的。
    在这里插入图片描述
    总结
  • 针对大于等于条件的唯一索引范围查询的情况下,如果条件值得记录存在于表中,该查询是等值擦汗寻,所以该记录锁对应得索引中锁退化为记录锁
针对小于等于的范围查询
  • 第一个数据增加的是next-key锁,限定是(-∞,a]

    • 保证不能在a之前插入数据
  • 后续每一个索引,加的锁都是next-key锁,限定范围是(left_edge,right-edge】

    • 保证上一个匹配到当前匹配之间的范围内,不增加任何新的数据
  • 找到第一个不满足约束条件的索引,当前退化为间隙锁

    • 保证在最后一个匹配的样本,到第一个不匹配的样本的范围内,不会插入新的元素

在这里插入图片描述

非唯一索引等值查询
  • 当我们使用非唯一索引进行等值查询的时候,存在两个索引,一个主键索引,还有一个是非唯一索引
    • 加锁的时候,会同时对两个索引都加锁
    • 对主键索引加锁的时候,只有对满足查询条件的记录,才会对主键索引进行加锁。

查询记录存在并且使用的不是唯一索引

非唯一索引等值查询过程

  • 对整个表格进行扫描,直到扫描到第一个不符合条件条件的二级索引记录,就会停止扫描
  • 再扫描过程中,对于的扫描到的二级索引记录增加的是next-key锁,
  • 对于第一个不符合条件的二级索引记录,该二级索引的next-key锁退化为间隙锁,
  • 对于符合查询条件的记录的主键索引加上记录锁。
记录不存的情况
  • 首先会对非唯一索引进行排序,找到第一个不满足等值条件的记录,
    • 二级索引,退化为间隙锁。
      在这里插入图片描述

在这里插入图片描述

  • 能不能插入成功,是需要考虑到二级索引底层结构的实现,首先对二级索引进行排序,然后再具有相同二级索引的记录的主键索引进行排序。
    在这里插入图片描述
记录存在的时候

在这里插入图片描述

  • 加锁过程具体如下
    • 符合条件的记录的主键索引退化成记录锁
    • 二级索引当前锁保持不变
    • 第一个不满足条件的二级索引,退化为间隙锁。

在这里插入图片描述

非唯一 索引范围查询
  • 非唯一索引查询,索引的nextkey 不会退化成间隙锁和记录锁的情况,二级索引加的也是next-key锁
    • 满足条件的主键索引仍旧是记录锁

在这里插入图片描述
在这里插入图片描述

没有加索引的查询
  • 如果锁定读查询语句,没有使用索引列座位查询条件,或者查询语句没有走索引查询,导致扫描是全表扫描的
    • 每一条记录的索引上,都会加next-key锁,锁住全表

不走索引,只要是执行update、delete、for update都是锁住整个表

总结

  • 想想就难受呀,拼多多主管面,就剩下最后一面了,那个主管面,基本上什么都没答出来,很难受,但凡那里看了一遍,我都不至于面试面的那么差,而且很多东西都很基础,我就是忘记了。没注意到这些细节,很难受!
  • 不想了,技不如人,没有准备好,那几天太浪了,没有好好备战,活该吧!后续提前批,要加把劲!
  • 事情蛮多的,这里太细了,不过大概懂了就行了。今晚还得赶着刷两道题,还得写一个党政结课的论文。

所有的加锁还有所退化,都是的为了避免幻读!!

当前读一定要使用索引进行操作,否则就是全表锁住

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

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

相关文章

【python脚本】批量检测sql延时注入

文章目录 前言批量检测sql延时注入工作原理脚本演示 前言 SQL延时注入是一种在Web应用程序中利用SQL注入漏洞的技术,当传统的基于错误信息或数据回显的注入方法不可行时,例如当Web应用进行了安全配置,不显示任何错误信息或敏感数据时&#x…

Element中的消息提示组件Message和弹框组件MessageBox

简述:在 Element UI 中,Message和MessageBox都是比较常用的组件,Message用来提示消息,而MessageBox是一个用于创建模态对话框的组件。它可以用于在页面上快速展示信息、警告或错误提示,而不会阻止用户的其他操作。简单…

Pandas_DataFrame读写详解:案例解析(第24天)

系列文章目录 一、 读写文件数据 二、df查询数据操作 三、df增加列操作 四、df删除行列操作 五、df数据去重操作 六、df数据修改操作 提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 系列文章目录前言一、 读写文…

华为DCN之:SDN和NFV

1. SDN概述 1.1 SDN的起源 SDN(Software Defined Network)即软件定义网络。是由斯坦福大学Clean Slate研究组提出的一种新型网络创新架构。其核心理念通过将网络设备控制平面与数据平面分离,从而实现了网络控制平面的集中控制,为…

深入理解C++中的锁

目录 1.基本互斥锁(std::mutex) 2.递归互斥锁(std::recursive_mutex) 3.带超时机制的互斥锁(std::timed_mutex) 4.带超时机制的递归互斥锁(std::recursive_timed_mutex) 5.共享…

图解 Kafka 架构

写在前面 Kafka 是一个可横向扩展,高可靠的实时消息中间件,常用于服务解耦、流量削峰。 好像是 LinkedIn 团队开发的,后面捐赠给apache基金会了。 kafka 总体架构图 Producer:生产者,消息的产生者,是消息的…

android AIDL使用demo

背景 最近打算学习一下如何在framework层添加一个自定义service。 了解到自定义service需要使用aidl,为了加强对aidl的了解和使用过程,特意又温习了一下aidl的使用,并用博客的形式记录下来。 aidl官方参考:https://developer.and…

不同系统间数据交换要通过 api 不能直接数据库访问

很多大数据开发提供数据给外部系统直接给表结构,这是不好的方式。在不同系统间进行数据交换时,通过API(应用程序编程接口)而非直接访问数据库是现代系统集成的一种最佳实践。 目录 为什么要通过API进行数据交换如何通过API进行数据…

论文辅导 | 基于多尺度分解的LSTM⁃ARIMA锂电池寿命预测

辅导文章 模型描述 锂电池剩余使用寿命(Remaining useful life,RUL)预测是锂电池研究的一个重要方向,通过对RUL的准确预测,可以更好地管理和维护电池,延长电池使用寿命。为了能够准确预测锂电池的RUL&…

STM32 看门狗 HAL

由时钟图可以看出看门狗采用的是内部低速时钟,频率为40KHz 打开看门狗,采用32分频,计数1250。 结合设置的分频系数和重载计数值,我们可以计算出看门狗的定时时间: 32*1250/40kHz 1s 主函数中喂狗就行 HAL_IWDG_Ref…

STM32 HAL库读取ID

在stm32f1xx_hal.c文件中由读取ID号的子函数,不同单片机的UID_BASE不同,本单片机用的是STM32F103CBT6,跳转之后可以看到地址为:0x1FFFF7E8 在程序中只需定义一个数组调用读取ID的函数即可 uint32_t UID[3]; while(1) { UID[0] HAL_GetUIDw0…

catia数控加工仿真铣平面粗加工

1,零件建模,毛坯建模 2 在毛坯上建立坐标系 3 添加资料刀具 4,双击对相关加工信息做设置 5 Roughing 加工设置 高亮红色区域是必选的,其他可以默认 6 完成加工仿真 7 加工余量

EasyExcel4导入导出数据(基于MyBatisPlus)

一、POM依赖 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><m…

Camera Raw:编辑 - 细节

Camera Raw “编辑”模块中的细节 Detail面板用于增强照片的锐度和减少噪点。通过对锐化和降噪进行精细调整&#xff0c;可以提高图像的清晰度&#xff0c;减少噪点&#xff0c;提高图像质量。 ◆ ◆ ◆ 使用方法与技巧 1、增强照片锐度 较小的“半径”&#xff0c;较大的“细…

如何解决大文件传输存在的痛点,实现高效流转?

在当代的数字化时代&#xff0c;数据资产在各行各业中扮演着举足轻重的角色&#xff0c;而数据的流通与交换则是其价值得以实现的关键。企业在进行大文件传输时&#xff0c;都面临着诸多挑战&#xff0c;比如网络延迟、大小受限、安全风险等。因此&#xff0c;如何高效安全的进…

springboot个人证书管理系统16679

springboot个人证书管理系统 摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了个人证书管理系统的开发全过程。通过分析个人证书管理系统管理的不足&#xff0c;创建了一个计算机管理个人证书管理系统的方案。文…

3、FTL基本工作过程

上文描述了FTL的四大功能&#xff0c;这里简述一下每个功能的含义。 地址转换简述 FTL要维护一个地址转换表&#xff0c;这个转换表是主机读/写硬盘的逻辑地址到硬盘实际物理地址的转换关系。 假如SSD的容量是128G&#xff0c;SSD逻辑块的大小是4KB&#xff0c;那SSD的逻辑块…

Linux系统的服务——以Centos7为例

一、Linux系统的服务简介 服务是向外部提供对应功能的进程&#xff0c;其运行在系统后台&#xff0c;能够7*24小时持续不断的提供外界随时发来的服务请求&#xff0c;且服务进程常驻在内存中&#xff0c;具有固定的端口号&#xff0c;通过端口号就能找到服务内容。 提供服务的一…

Linux源码阅读笔记10-进程NICE案例分析2

set_user_nice set_user_nice函数功能&#xff1a;设置某一进程的NICE值&#xff0c;其NICE值的计算是根据进程的静态优先级&#xff08;task_struct->static_prio&#xff09;&#xff0c;直接通过set_user_nice函数更改进程的静态优先级。 内核源码 void set_user_nice…

Unity3d C#实现基于UGUI ScrollRect的轮播图效果功能(含源码)

前言 轮播功能是一种常见的页面组件&#xff0c;用于在页面中显示多张图片/素材并自动或手动进行切换&#xff0c;以提高页面的美观度和用户体验。主要的功能是&#xff1a;自动/手动切换;平滑的切换效果;导航指示器等。可惜Unity的UGUI系统里没有现成的实现该功能&#xff0c…