一文读懂 MySQL 锁

2023-10-26

1 MySQL 锁简介

1.1 什么是锁

锁是计算机用以协调多个进程间并发访问同一共享资源的一种机制。MySQL中为了保证数据访问的一致性与有效性等功能,实现了锁机制,MySQL中的锁是在服务器层或者存储引擎层实现的。

1.2 锁用来解决什么问题

锁是用来解决并发事务的访问问题,我们已经知道事务并发执行时可能带来的各种问题,最大的一个难点是:一方面要最大程度地利用数据库的并发访问,另外一方面还要确保每个用户能以一致的方式读取和修改数据,尤其是一个事务进行读取操作,另一个同时进行改动操作的情况下。

一个事务进行读取操作,另一个进行改动操作,我们前边说过,这种情况下可能发生脏读、不可重复读、幻读的问题。

怎么解决脏读、不可重复读、幻读这些问题呢?其实有两种可选的解决方案:

方案一:读操作MVCC,写操作进行加锁

该方案性能较好,但可能会读到旧版本记录

方案二:读写操作都加锁

该方案性能一般,但是每次都可以读取到最新的记录,比如在银行场景中,对安全性要求非常高

2 锁的分类

MySQL 中锁有很多,按照模式、粒度等可以分为如下几种类型

image-20221003154244472

3 乐观悲观锁

3.1 乐观锁

1、概念

乐观锁,顾名思义,就是非常乐观,乐观锁认为数据一般情况下不会造成冲突,所以在数据提交更新的时候才会去检测。

2、实现

乐观锁是基本版本号机制实现的,数据表中增加一个 version 字段,读取数据时将 version 一起读出。数据每更新一次,version 字段值 + 1。当修改需要提交时,将读取时的版本号与数据库当前版本号做比较,如果一致,说明在此期间无人修改这条记录,不一致则说明已经被修改了,提交失败。

3、适用场景

乐观锁适用于读操作多,写操作少的场景

3.2 悲观锁

1、概念

悲观锁是相比较乐观锁而言的,就是比较悲观,悲观锁认为数据每次操作都会被修改,所以在每次操作数据时都会加上锁。

2、实现

悲观锁通过共享锁和排他锁实现(下面会讲到这两种锁)

3、适用场景

适用于并发量不大,写操作多,读操作少的场景

4 共享排他锁

4.1 共享锁

1、概念

共享锁,又称读锁,简称 S 锁。当事务对数据加上读锁后,其他事务只能对该数据加读锁,不能加写锁。

2、实现

共享锁加锁方法:select …lock in share mode

image-20221003172941494

image-20221003173149274

4.2 排他锁

1、概念

排他锁,又称为写锁,简称 X 锁,当事务对数据加上排他锁后,其他事务无法对该数据进行查询或者修改

MySQL InnoDB引擎默认 update,delete,insert 都会自动给涉及到的数据加上排他锁,select 语句默认不会加任何锁类型。

2、实现

排他锁加锁方式:select …for update

image-20221003173825780

image-20221003173942828

5 粒度锁

5.1 全局锁

1、概念

全局锁,从名称上可以理解,全局锁就是对整个 MySQL 数据库实例加锁,加锁期间,对数据库的任何增删改操作都无法执行。

2、实现

MySQL 提供了一个加全局读锁的方法,命令是Flush tables with read lock (FTWRL)

3、适用场景

全库数据备份,可以使用全局锁,其他情况不要使用

5.2 表级锁

1、概念

表级锁,给当前操作的这张表加锁, MyISAM 与 InnoDB 引擎都支持表级锁定

MySQL 里面表级别的锁有两种:一种是表锁,一种是元数据锁(meta data lock,MDL)

2、实现

加表锁:lock table read/write

image-20221003175254955

image-20221003175706554

解除表锁:

第一步:找出被锁的表

show processlist

image-20221003180108421

第二步:kill 掉锁表的进程

kill 21;
kill 22;

再次更新 user 表数据

image-20221003180453415

可以正常更新了

5.3 页级锁

页级锁是 MySQL 中锁定粒度介于行级锁和表级锁中间的一种锁。表级锁速度快,但冲突多,行级冲突少,但速度慢。因此,采取了折衷的页级锁,一次锁定相邻的一组记录。BDB 引擎支持页级锁

5.4 行级锁

1、概念

行级锁是 MySQL 粒度最细的锁,发生锁冲突概率最低,但是加锁慢,开销大

MySQL 中只有 InnoDB 引擎支持行锁,其他不支持

2、实现

MySQL 中,行级锁并不是之间锁记录,而是锁的索引。MySQL 在执行 update、delete 语句时会自动加上行锁

image-20221003181021358

image-20221003181133774

6 意向锁

1、概念

意向锁是表锁,为了协调行锁和表锁的关系,支持多粒度(表锁与行锁)的锁并存

2、作用

当有事务A有行锁时,MySQL会自动为该表添加意向锁,事务B如果想申请整个表的写锁,那么不需要遍历每一行判断是否存在行锁,而直接判断是否存在意向锁,增强性能。

3、兼容性

意向共享锁(IS) 意向排他锁(IX)
共享锁 兼容 互斥
排他锁 互斥 互斥

7 间隙临键记录锁

1、概念

记录锁、间隙锁、临键锁都是排它锁,而记录锁的使用方法跟排它锁介绍一致。

7.1 记录锁

记录锁是封锁记录,记录锁也叫行锁,例如:

select * from user where id = 1 for update;

它会在 id=1 的记录上加上记录锁,以阻止其他事务插入,更新,删除 id=1 这一行。

7.2 间隙锁

间隙锁基于非唯一索引,它锁定一段范围内的索引记录。使用间隙锁锁住的是一个区间,而不仅仅是这个区间中的每一条数据

select * from user where id < 10 for update;

即所有在 [1,10)区间内的记录行都会被锁住,所有id 为 1、2、3、4、5、6、7、8、9 的数据行的插入会被阻塞

image-20221003182325290

image-20221003182340884

7.3 临键锁

临键锁,是记录锁与间隙锁的组合,它的封锁范围,既包含索引记录,又包含索引区间,是一个左开右闭区间。临键锁的主要目的,也是为了避免幻读(Phantom Read)。如果把事务的隔离级别降级为RC,临键锁则也会失效。

每个数据行上的非唯一索引列上都会存在一把临键锁,当某个事务持有该数据行的临键锁时,会锁住一段左开右闭区间的数据。需要强调的一点是,InnoDB 中行级锁是基于索引实现的,临键锁只与非唯一索引列有关,在唯一索引列(包括主键列)上不存在临键锁。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

一文读懂 MySQL 锁 的相关文章

随机推荐

  • 解决axios发送数据到后端中文乱码问题

    解决axios发送数据到后端中文乱码问题 axios请求 const that this axios method post url http localhost 8080 2 SelectByIdServlet data this stu
  • Altium Designer22中修改元件库后,更新原理图的2种方法及这2种方法的区别。

    PCB设计过程中 经常会涉及到修改原理图库和PCB库的情况 那么修改了这些库之后 如何更新到已经绘制好的原理图中呢 更新过程中 如果想保留设置好的description footprint和value等属性 又该如何设置呢 方法一 在原理图
  • python3:retrying模块

    retrying是一个python的重试包 可以用来自动重试一些可能运行失败的程序段 retrying提供一个装饰器函数retry 被装饰的函数就在运行失败的情况下将重新执行 默认只要一直报错就会不断重试 Web sit https git
  • FPGA零基础学习之Vivado-RTC实时时钟系统设计

    FPGA零基础学习之Vivado RTC实时时钟系统设计 本系列将带来FPGA的系统性学习 从最基本的数字电路基础开始 最详细操作步骤 最直白的言语描述 手把手的 傻瓜式 讲解 让电子 信息 通信类专业学生 初入职场小白及打算进阶提升的职业
  • mobx的使用

    mobx的使用 1 API mobx react Provider 包裹根组件 用于传递数据 observer 组件变为响应式 inject 接收mobx实例 用于类组件 MobXProviderContext mobx observabl
  • 远程控制---实验九:IPC远程植入木马

    目录 一 实验目的及要求 二 实验原理 IPC 空会话 IPC建立的过程 木马 三 实验环境 四 实验步骤及内容 五 实验总结 六 分析与思考 一 实验目的及要求 1 掌握利用 IPC 入侵目标计算机 windows XP 或 window
  • Java虚拟机内存参数设置

    Java虚拟机内存参数设置 前言 Java虚拟机 JVM 是一种抽象的计算机器 JVM是一个程序 对于编写在其中执行的程序来说 它看起来像一台机器 通过这种方式 Java程序被写入相同的接口和库集 针对特定操作系统的每个JVM实现都将Jav
  • 使用nginx反向代理docker安装的jenkins

    描述 使用nginx反向代理jenkins nginx反向代理 docker安装的jenkins 方法 一 nginx反向代理docker安装的jenkins 1 使用 vim etc nginx nginx conf进入nginx 的配置
  • Typescript类型注解和类型推断

    在TypeScript中有两个基本概念 类型注解和类型推断 这两个概念在我们使用TypeScript代码时会一直使用 一 类型注解 type annotation 如 let count number count 123 这种就是类型注解
  • QT运行出现The CDB process terminated解决办法(亲测有效)

    QT运行出现The CDB process terminated解决办法 运行程序时出现如图所示的问题 检查2件事 1 检查编译器和调试器 工具 选项 构建和运行 如果是电脑图标证明不是这里的问题 如果出现黄色的感叹号证明编译器和调试器没有
  • XNA简介

    href file C DOCUME 1 ADMINI 1 LOCALS 1 Temp msohtml1 02 clip filelist xml rel File List gt XNA简介 XNA简介 首先声明 XNA不是游戏引擎 它只
  • linux g++编译以及库多重依赖

    目录 一 编译命令 二 编译相关选项 三 静态库和动态库的编译命令 1 生成动态库和静态库 2 fPIC选项 3 如何解决运行时找不到链接库的问题 四 库多重依赖 1 动态库依赖动态库 2 动态库依赖静态库 3 静态库依赖静态库 一 编译命
  • 用了很多年的PC端离线版个人知识管理软件PKM2 Manager推荐给大家

    对于从事IT行业的童鞋来说 每人每天每月都会遇到大量的新知识与旧知识出现在眼前 从而就会出现知识容易遗忘 经验容易流失的情况 比如 曾经遇到过的某类问题 今天再次出现了 或曾经做过一次事情步骤 今天要再次重新做一遍等等 对这些众多的知识若没
  • 最难用的鼠标键、设置半天、反人类逻辑(罗技)

    目的 高效设置罗技鼠标键 提高复制粘贴效率 准备软件 Logitech G HUB Logitech 支持 下载 1 右上角 点击箭头 点击管理配置文件 2 左下角 点击加号 创建配置文件 办公 3 点击办公 4 右上角选择 办公 底部点击
  • YOLO算法概述与细节

    R CNN系列算法是two stage 两步走算法 yolo和ssd属于one stage算法 yolo v1 把图片分成若干个小区域 每个小区域负责检测是否有物体的中心点落在其中 每个小区域可预测多个box 但是只能检测一个物体 算法首先
  • 在C++中实现foreach循环,比for_each更简洁!

    原文 http blogread cn it article 2570 f sr python c java里面都有类似于foreach的结构 stl里面虽然有for each这个函数 但是感觉使用还是太繁琐了一些 所以就自己实现了一个 先
  • docker搭建lanproxy内网穿透服务

    docker搭建lanproxy内网穿透服务 一 服务端 1 1 安装docker 1 2 安装nginx 1 3 域名解析 1 4 安装lanproxy server 1 5 配置 nginx 反向代理 1 6 继续配置 lanproxy
  • JZ76 删除链表中重复的结点

    JZ76 删除链表中重复的结点 描述 在一个排序的链表中 存在重复的结点 请删除该链表中重复的结点 重复的结点不保留 返回链表头指针 例如 链表 1 gt 2 gt 3 gt 3 gt 4 gt 4 gt 5 处理后为 1 gt 2 gt
  • centos忘记root密码后如何重置!

    忘记系统管理员密码真是件头疼的事 centos7的拯救之路如下 第一步 重启系统 按 e 进入启动文件界面后 第二步 按 拉到底部 找到linux16这一行 将ro改成rw 在这行最后面加上 init bin sh 第三步 然后按 Ctrl
  • 一文读懂 MySQL 锁

    1 MySQL 锁简介 1 1 什么是锁 锁是计算机用以协调多个进程间并发访问同一共享资源的一种机制 MySQL中为了保证数据访问的一致性与有效性等功能 实现了锁机制 MySQL中的锁是在服务器层或者存储引擎层实现的 1 2 锁用来解决什么