MySQL 的锁

目录

一、锁的分类

二、全局锁、表级锁、页级锁、行级锁

三、乐观锁和悲观锁

四、共享锁和排它锁

五、意向共享锁和意向排它锁

六、间隙锁、临键锁、记录锁


锁的分类和用途

一、锁的分类

1、MySQL锁可以按模式分类为:

  • 乐观锁
  • 悲观锁。

2、按粒度分可以分为:

  • 全局锁
  • 表级锁
  • 页级锁
  • 行级锁。

3、按属性可以分为:

  • 共享锁
  • 排它锁。

4、按状态分为:

  • 意向共享锁
  • 意向排它锁。

5、按算法分为:

  • 间隙锁
  • 临键锁
  • 记录锁。

二、全局锁、表级锁、页级锁、行级锁

1、全局锁

(1) 概念

全局锁就是对整个数据库实例加锁。

(2) 应用场景

全库逻辑备份(mysqldump)
(3) 实现方式

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

当你需要让整个库处于只读状态的时候,可以使用这个命令,之后其他线程的以下语句会被阻塞:数据更新语句(数据的增删改)、数据定义语句(包括建表、修改表结构等)和更新类事务的提交语句。

风险点:

  • 如果在主库上备份,那么在备份期间都不能执行更新,业务基本上就能停止。
  • 如果在从库上备份,那么备份期间从库不能执行主库同步过来的binlog,会导致主从延迟。

解决办法:
mysqldump使用参数--single-transaction,启动一个事务,确保拿到一致性视图。而由于MVCC的支持,这个过程中数据是可以正常更新的。

2. 表级锁

(1) 概念

当前操作的整张表加锁,最常使用的 MyISAM 与 InnoDB 都支持表级锁定。

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

(2) 实现方式

表锁:lock tables … read/write;

例如lock tables t1 read, t2 write; 命令,则其他线程写 t1、读写 t2 的语句都会被阻塞。同时,线程 A 在执行 unlock tables 之前,也只能执行读 t1、读写 t2 的操作。连写 t1 都不允许,自然也不能在unlock tables之前访问其他表。

元数据锁:MDL 不需要显式使用,在访问一个表的时候会被自动加上,在 MySQL 5.5 版本中引入了 MDL,当对一个表做增删改查操作的时候,加 MDL读锁;当要对表做结构变更操作的时候,加 MDL 写锁。

(3) 风险点:
给一个表加字段,或者修改字段,或者加索引,需要扫描全表的数据。在对大表操作的时候,肯定会特别小心,以免对线上服务造成影响。而实际上,即使是小表,操作不慎也会出问题。

(4) 解决办法

首先我们要解决长事务,事务不提交,就会一直占着 MDL 锁。在 MySQL 的information_schema 库的 innodb_trx 表中,你可以查到当前执行中的事务。如果你要做 DDL 变更的表刚好有长事务在执行,要考虑先暂停 DDL,或者 kill 掉这个长事务。这也是为什么需要在低峰期做ddl 变更。

3、页级锁

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

4.行级锁

(1) 概念

行级锁是粒度最低的锁,发生锁冲突的概率也最低、并发度最高。但是加锁慢、开销大,容易发生死锁现象。

MySQL中只有InnoDB支持行级锁,行级锁分为共享锁排他锁

(2) 实现方式

在MySQL中,行级锁并不是直接锁记录,而是锁索引。索引分为主键索引和非主键索引两种,如果一条sql语句操作了主键索引,MySQL就会锁定这条主键索引;如果一条语句操作了非主键索引,MySQL会先锁定该非主键索引,再锁定相关的主键索引。在UPDATE、DELETE操作时,MySQL不仅锁定WHERE条件扫描过的所有索引记录,而且会锁定相邻的键值,即所谓的next-key locking。

三、乐观锁和悲观锁

1. 乐观锁

(1) 概念

乐观锁是相对悲观锁而言的,乐观锁假设数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则返回给用户错误的信息,让用户决定如何去做。

(2) 应用场景

适用于读多写少,因为如果出现大量的写操作,写冲突的可能性就会增大,业务层需要不断重试,会大大降低系统性能。

2. 悲观锁

(1) 概念

悲观锁,正如其名,具有强烈的独占和排他特性,每次去拿数据的时候都认为别人会修改,对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中,将数据处于锁定状态。

(2) 应用场景

适用于并发量不大、写入操作比较频繁、数据一致性比较高的场景。

(3) 实现方式

在MySQL中使用悲观锁,必须关闭MySQL的自动提交,set autocommit=0。共享锁排它锁悲观锁的不同的实现,它俩都属于悲观锁的范畴。

四、共享锁和排它锁

1. 共享锁

(1) 概念

共享锁,又称之为读锁,简称S锁,当事务A对数据加上读锁后,其他事务只能对该数据加读锁,不能做任何修改操作,也就是不能添加写锁。只有当事务A上的读锁被释放后,其他事务才能对其添加写锁。

(2) 应用场景

共享锁主要是为了支持并发的读取数据而出现的,读取数据时,不允许其他事务对当前数据进行修改操作,从而避免”不可重读”的问题的出现

适合于两张表存在关系时的写操作,拿mysql官方文档的例子来说,一个表是child表,一个是parent表,假设child表的某一列child_id映射到parent表的c_child_id列,那么从业务角度讲,此时我直接insert一条child_id=100记录到child表是存在风险的,因为刚insert的时候可能在parent表里删除了这条c_child_id=100的记录,那么业务数据就存在不一致的风险。正确的方法是再插入时执行select * from parent where c_child_id=100 lock in share mode,锁定了parent表的这条记录,然后执行insert into child(child_id)values (100)就不会存在这种问题了。

(3) 实现方式

select …lock in share mode

2. 排它锁

(1) 概念

排它锁,又称之为写锁,简称X锁,当事务对数据加上写锁后,其他事务既不能对该数据添加读写,也不能对该数据添加写锁,写锁与其他锁都是互斥的。只有当前数据写锁被释放后,其他事务才能对其添加写锁或者是读锁。

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

(2) 应用场景

写锁主要是为了解决在修改数据时,不允许其他事务对当前数据进行修改和读取操作,从而可以有效避免”脏读”问题的产生

(3) 实现方式

select …for update

五、意向共享锁和意向排它锁

1. 概念

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

2. 作用

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

3. 意向锁的兼容互斥性

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

六、间隙锁、临键锁、记录锁

概念

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

1、记录锁

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

select *from goods where **`id`=**1 for update;

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

2、间隙锁

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

select* from goods where id between 1 and 10 for update;

即所有在(1,10)区间内的记录行都会被锁住,所有id 为 2、3、4、5、6、7、8、9 的数据行的插入会被阻塞,但是 1和 10 两条记录行并不会被锁住。

3、临键锁

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

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


巨人的肩膀:史上最全MySQL各种锁详解 - 掘金

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

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

相关文章

STM32H743烧录后无法识别Jlink的问题

利用Cubemx生成H743的代码,点击烧录后,无法再识别到Jlink了,只能烧录时按着复位再松开(类似51单片机)。 烧录后不运行,用keil进行debug,调试发下芯片进去内存管理错误中断。 经过不断调试发现&…

功能强大UI美观的视频答题猜歌闯关娱乐微信小程序源码

正文: 功能强大UI美观的视频答题猜歌闯关娱乐微信小程序源码下载 后台管理资源本地化带数据和视频教程,这是一款拥有后端的闯关娱乐小程序。支持个人小程序和企业小程序上线运营功能强大齐全,带数据本地化(数据在自己服务器自己管理无需担心第三方失效…

为什么电源纹波那么大?

某用户在用500MHz带宽的示波器对其开关电源输出5V信号的纹波进行测试时&#xff0c;发现纹波和噪声的峰峰值达到了900多mV&#xff08;如下图所示&#xff09;&#xff0c;而其开关电源标称的纹波的峰峰值<20mv。虽然用户电路板上后级还有LDO对开关电源的这个输出再进行稳压…

如何判断一个点是否在凸多边形内 - golang

判断一个点是否在凸多边形内的方法很多&#xff0c;此处仅给出使用向量叉积法判断点是否在凸多边形内的方法。 以下图为例说明问题&#xff1a; 原理&#xff1a; 1. 将多边形的第 i 条边的第一个顶点指向点 P 得到向量 v1&#xff0c;然后将从第一个顶点指向第二个顶点得到向…

网络安全真的那么好吗?

当你开始在网上搜索关于网络安全的学习资料&#xff0c;常常会陷入自我怀疑&#xff1a;尝试自学后能使用工具进行简单的扫描和挖洞&#xff0c;但总感觉后期学习很难有突破&#xff0c;不知道是哪里出现问题…于是又不得不推倒重来。 了解网络安全&#xff0c;首先要搞清楚下…

ES6-ES13学习笔记(5.0)

ES2022的函数 //findLast findLastIndex() ES2022 发现在电脑自带的联想浏览器不支持此函数&#xff0c;还报错了 对于ECMA的支持还和浏览器有关以及浏览器版本有关&#xff0c;然后我使用Google浏览器就可以正常使用&#xff0c; 1.扩展运算符&#xff1a;三个点... ..…

Python安装

一、Windows安装 打开官网&#xff1a;https://www.python.org/getit/ 下载exe安装包&#xff0c;双击安装默认选择路径 2、验证安装成功 cmd: python 能看到版本 cmd&#xff1a;pip 测试包管理工具 cmd&#xff1a;python -m pip install --user --upgrade pip -i https:…

高考开始了,计算机专业未来还会火吗?

2023年高考&#xff0c;今天开始第一场考试。而走出考场&#xff0c;考生们也将面临选报专业的难题。高考人数逐年攀升&#xff0c;录取率却不断下降。 过去10年&#xff0c;计算机专业可谓红透半边天&#xff0c;早早进入这个行业的&#xff0c;基本都吃到了很高的红利。然而…

java多线程面试题

一、创建线程有哪几种方式? 创建线程有三种方式&#xff0c;分别是继承Thread类、实现Runnable接口、实现Callable接口。 Runnable接口与Callable接口的方式基本相同&#xff0c;只是Callable接口里定义的方法有返回值&#xff0c;可以声明抛出异常。 二、run()和start()有什…

006-从零搭建微服务-注册中心(二)

写在最前 如果这个项目让你有所收获&#xff0c;记得 Star 关注哦&#xff0c;这对我是非常不错的鼓励与支持。 源码地址&#xff1a;https://gitee.com/csps/mingyue 文档地址&#xff1a;https://gitee.com/csps/mingyue/wikis 核心依赖 需要注册配置中心的服务引入下面 …

vuex核心

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、什么是状态管理&#xff1f;二、复杂的状态管理1.随着代码越来越多&#xff0c;需要管理的状态越来越复杂&#xff0c;当多个组件共享状态时&#xff0c;单…

chatgpt赋能python:Python如何运行两次

Python如何运行两次 Python是一种高级编程语言&#xff0c;非常受欢迎&#xff0c;因为它易于学习&#xff0c;简单易用&#xff0c;开放性强&#xff0c;而且功能强大。Python常用于处理各种任务&#xff0c;包括数据分析、Web应用开发、人工智能、自动化测试等。此外&#x…

Linux ls -l输出文件信息详解

在linux中&#xff0c;我们知道一切皆为文件&#xff0c;经常我们会使用ls -l去查看文件的信息&#xff0c;今天会大家详细讲解一下ls -l输出的文件属性信息。 1.ls -l输出 命令&#xff1a; ls -l 通过ls -l命令输出&#xff0c;我们可以看到上图中的属性信息输出&#xff…

PMP证书含金量也太高了吧!在一线城市可享受多项福利~

近年来&#xff0c;企业与企业、城市与城市间的人才争夺变得更加激烈&#xff0c;各大城市为了泛集聚和培养重点领域紧缺专业人才均针对持有国际职业资格认证的人才出台了相关优惠政策&#xff0c;目前我了解到的已有以下5个城市针对PMP项目管理及相关行业和认证出台了鼓励政策…

项目管理系统的设计与实现(ASP.NET,SQL)

开发环境&#xff1a;Microsoft Visual Studio 数据库&#xff1a;Microsoft SQL Server 程序语言&#xff1a;asp.NET(C#)语言本系统的开发使各大公司所的项目管理更加方便快捷&#xff0c;同时也促使项目的管理变的更加系统化、有序化。系统界面较友好&#xff0c;易于操作。…

MySQL CAST 函数与 CONVERT 函数

文章目录 CAST 函数与 CONVERT 函数1. 数字和小数点组成的字符串转换为整型2. 非数值字符串转换为整型3. 把整型转换为二进制4. 数字和小数点组成的字符串转换为浮点型 CAST 函数与 CONVERT 函数 前面我们介绍的两个函数用于字符串和日期类型之间进行相互转换&#xff0c;有时我…

什么?要求设计一个循环队列?

&#x1f388;个人主页:&#x1f388; :✨✨✨初阶牛✨✨✨ &#x1f43b;推荐专栏: &#x1f354;&#x1f35f;&#x1f32f;C语言初阶 &#x1f354;&#x1f35f;&#x1f32f;C语言进阶 &#x1f511;个人信条: &#x1f335;知行合一 &#x1f349;本篇简介:>:讲解用c…

直播问答功能(互动功能接收端JS-SDK)

功能概述 本模块主要用于展示问答模块。 初始化及销毁 在实例化该模块并进行使用之前&#xff0c;需要对SDK进行初始化配置&#xff0c;详细见参考文档。 在线文件引入方式 // script 标签引入&#xff0c;根据版本号引入JS版本。 <script src"https://websdk.vi…

10课程设计收尾及优秀作品展示答辩【FPGA模型机课程设计】

10课程设计收尾及优秀作品展示答辩【FPGA模型机课程设计】 前言说明推荐10课程设计收尾及优秀作品展示答辩安排 目录一、单周期CPU的设计过程1、基本的20条指令固定指令格式设计I 型指令设计J型指令设计lw sw指令设计 2、扩展的20条指令J型扩展指令设计乘法除法指令格式 3、实现…

什么是lamp架构

LAMP架构介绍 LAMP动态网站架构 LAMP是指一组通常一起使用来运行动态网站或者服务器的自由软件名称首字母缩写。 1、LAMP分别代表什么&#xff1f; L代表服务器操作系统使用LinuxA代表网站服务使用的是Apache软件基金会中的httpd软件M代表网站后台使用的数据库是MySQL数据库…