MySql中的锁的分类

锁的分类

        MySQL锁可以按模式分类为:乐观锁与悲观锁。按粒度分可以分为全局锁、表级锁、页级锁、行级锁。按属性可以分为:共享锁、排它锁。按状态分为:意向共享锁、意向排它锁。按算法分为:间隙锁、临键锁、记录锁。

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

1. 全局锁

(1) 概念

        全局锁就对整个数据库实例加锁,加锁后整个实例就处于只读状态,后续的MDL、DDL语句、更新操作的事务提交语句都将被阻塞。

(2) 应用场景

做全库的逻辑备份、全库的导出,对所有的表进行锁定,从而获取一致性视图,保证数据的完整性。

(3) 实现方式

最常用的全局锁是读锁和写锁。

读锁(共享锁):它阻止其他用户更新数据,但允许他们读取数据。这在你需要在一段时间内保持数据一致性时很有用。

写锁(排他锁):它阻止其他用户读取和更新数据。这在你需要修改一些大量的数据,并且不希望其他用户在这段时间内干扰时很有用。

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

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

风险点:

如果在主库上备份,那么在备份期间都不能执行更新,业务基本上就能停止。

如果在从库上备份,那么备份期间从库不能执行主库同步过来的binlog,会导致主从延迟。

解决办法:

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

2. 表级锁

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

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

添加表锁,格式如下

lock tables xxx 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. 行级锁

        行级锁是粒度最低的锁,发生锁冲突的概率也最低、并发度最高。但是加锁慢、开销大,容易发生死锁现象。MySQL中只有InnoDB支持行级锁,行级锁可分为共享锁和排他锁。

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

注意事项:

行级锁只在事务中有效,也就是说,只有在一个事务开始后并在事务提交火回滚之前,才能对数据进行锁定。如果在非事务环境中指向SQL语句,那么InnDB会在语句执行结束后立即释放所有的锁。

在不通过索引条件查询的时候,InnoDB使用的是表锁,而不是行锁。

由于MySQL的行锁是针对索引加的锁,不是针对记录加的锁,所以即使是访问不同行的记录,如果使用了相同的索引键,也是会出现锁冲突的。

当表有多个索引的时候,不同的事务可以使用不同的索引锁定不同的行,另外,不论是使用主键索引、唯一索引或普通索引,InnoDB都会使用行锁来对数据加锁。

即便在条件中使用了索引字段,但具体是否使用索引来检索数据是由MySQL通过判断不同执行计划的代价来决定的,如果MySQL认为全表扫描效率更高,比如对一些很小的表,它就不会使用索引,这种情况下InnoDB将使用表锁,而不是行锁。因此,在分析锁冲突时,别忘了检查SQL的执行计划,以确认是否真正使用了索引。

4.意向锁

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

为什么意向锁是表级锁呢?
当我们需要加一个排他锁时,需要根据意向锁去判断表中有没不有数据行被锁定(行锁)
(1)如果意向锁是行锁,则需要遍历每一行数据去确认;
(2)如果意向锁是表锁,则只需要判断一次即可知道有没数据行被锁定,提升性能。
意向锁怎么支持表锁和行锁并存?
(1)首先明确并存的概念是指数据库同时支持表、行锁,而不是任何情况都支持一个表中同
时有一个事务A持有行锁、又有一个事务B持有表锁,因为表一旦但被上了一个表级的写锁,肯
定不能再上一个行级的锁。
(2)如果事务A对某一行上锁,其他事务就不可能修改这一行。这与"事务B锁住整个表就能
修改表中的任意一行"形成了冲突。所以,没有意向锁的时候,让行锁与表锁共存,就会带来
很多问题。于是有了意向锁的出现,如前面所言,数据库不需要在检查每一行数据是否有锁,
而是直接判断一次意向锁是否存在即可,能提升很多性能。

5.间隙锁

  间隙锁(Gap Lock)锁定的是索引记录之间的间隙、第一个索引之前的间隙或者最后一个索引之后的间隙。例如,SELECT * FROM t WHERE c1 BETWEEN 1 and 10 FOR UPDATE;会阻止其他事务将 1 到 10 之间的任何值插入到 c1 字段中,即使该列不存在这样的数据;因为这些值都会被锁定。

间隙锁的存在,主要是为了解决幻读问题。所谓幻读,是指在一个事务内读取某个范围的记录
时,另外一个事务在该范围内插入了新的记录,当第一个事务再次读取该范围的记录时,会发
现有些原本不存在的记录,这就是幻读。
举例来说,假设我们有一个存储学生信息的表,有一个事务A要查询年龄在10-20之间的学
生,它在查询前会对这个区间加锁。此时如果有另一个事务3想要插入一个年龄为15的学生,
由于这个年龄的范围已经被事务A锁定,所以事务B必须等待,直到事务A完成,释放锁。这样
就避免了幻读的产生。
值得注意的是,由于间隙锁会锁定范围,如果并发事务较多且涉及的数据范围有交集,可能会
引发性能问题,甚至死锁。因此,在设计数据库和选择隔离级别时,需要综合考虑数据一致性
和并发性能。

间隙锁有什么缺点?

间隙锁(Gap Locks)是MySQL的InnoDB存储引擎用于防止幻读问题的一种锁定机制,虽然

它在某些场景下非常有用,但也存在一些潜在的缺点,包括:

1.性能影响:间隙锁会阻止其他事务在已经锁定的范围内插入新的行,这可能会影响到数据库

的并发性能,尤其在需要大量插入操作的高并发场景下。

2.死锁风险:虽然间隙锁可以在某些情况下防止死锁,但在其他情况下,它可能会增加死锁的

风险。比如,两个事务都想在同一间隙中插入新的行,就可能发生死锁。

3.复杂性:理解间隙锁及其对事务的影响可能需要相当深入的数据库知识,尤其是在处理并发

问题和调优数据库性能时。

4.锁定范围可能过大:间隙锁锁定的是索引之间的间隙,这可可能会比实际需要锁定的行要多。

如果一个事务需要锁定的只是表中的一小部分行,但由于间隙锁的存在,可能会锁定更大范

围的数据,导致不必要的锁定冲突。

请注意,以上所述的缺点主要取决于具体的使用场景和工作负载,有时候,为了保持数据的一

致性和防止并发问题,这些缺点可能是可以接受的。

6.临键锁

        临键锁 (Next-Key) 可以理解为一种特殊的间隙锁,也可以理解为一种特殊的算法。通过临建锁可以解决幻读的问题。每个数据行上的非唯一索引列上都会存在一把临键锁,当某个事务持有该数据行的临键锁时,会锁住一段左开右闭区间的数据。需要强调的一点是,InnoDB中行级锁是基于索引实现的,临键锁只与非唯一索引列有关,在唯一索引列(包括主键列)上不存在临键锁。

例:

id age name

1 10 张三

3 24 李四

5 32 王五

7 45 赵六

该表中`age`列潜在的临键锁有:

(-∞,10]

(10,24]

(24,32]

(32,45]

(45,+∞]

7.记录锁

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

select *from goods where id=1 for update;

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

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

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

相关文章

ClickHouse与各种组件的关系

ClickHouse和其他组件关系如下: Flink支持ClickHouse Sink支持Hive/SparkSQL数据批量导入ClickHouseHetuEngine支持ClickHouse数据源常用第三方工具如DBeaver支持ClickHouse对接ClickHouse依赖ZooKeeper实现了分布式DDL执行以及ReplicatedMergeTree表主备节点之间的…

多线程—— JUC 的常见类

目录 前言 一、Callable 接口 1.Callable 介绍 2.代码示例 3.创建线程的方式 二、ReentrantLock 类 1.ReentrantLock 介绍 2.代码示例 3.与 synchronized 的区别 三、信号量 Semaphore 类 1.Semaphore 介绍 2.代码示例 3.保证线程安全的方式 四、CountDownLatch …

二、Spring的执行流程

文章目录 1. spring的初始化过程1.1 ClassPathXmlApplicationContext的构造方法1.2 refresh方法(核心流程)1.2.1 prepareRefresh() 方法1.2.2 obtainFreshBeanFactory() 方法1.2.3 prepareBeanFactory() 方法1.2.4 invokeBeanFactoryPostProcessors() 方…

(linux驱动学习 - 12). IIC 驱动实验

目录 一.IIC 总线驱动相关结构体与函数 1.i2c_adapter 结构体 2.i2c_algorithm 结构体 3.向系统注册设置好的 i2c_adapter 结构体 - i2c_add_adapter 4.向系统注册设置好的 i2c_adapter 结构体 - i2c_add_numbered_adapter 5.删除 I2C 适配器 - i2c_del_adapter 二.IIC 设…

【C++算法】11.滑动窗口_最大连续1的个数lll

文章目录 题目链接:题目描述:解法C 算法代码:图解 题目链接: 1004. 最大连续 1 的个数 III 题目描述: 解法 解法一:暴力枚举zero计数器 转化找出最长的子数组,0的个数不超过k个。 例如&#xf…

计算机网络——有连接传输层协议TCP

序号 序号一般不从0开始,这个在双方建立连接后约定一个数 这样做可以避免网络中滞留的TCP段对新的连接的干扰

Flutter状态管理

StatefulWidget按状态划分StatelessWidgetStatefulWidget 按照作用域划分组件内私有状态实现跨组件状态管理全局状态 状态组件的组成 DataTableInheritedWidget生命周期无状态组件有状态组件initState()didChangeDependencies()build()setState()didUpdateWidget()deactivate()…

Redis 集群 总结

前言 相关系列 《Redis & 目录》(持续更新)《Redis & 集群 & 源码》(学习过程/多有漏误/仅作参考/不再更新)《Redis & 集群 & 总结》(学习总结/最新最准/持续更新)《Redis & 集群…

二十二、Python基础语法(模块)

模块(module):在python中,每个代码文件就是一个模块,在模块中定义的变量、函数、类别人都可以直接使用,如果想要使用别人写好的模块,就必须先导入别人的模块,模块名须满足标识符规则(由字母、数…

【国潮来袭】华为原生鸿蒙 HarmonyOS NEXT(5.0)正式发布:鸿蒙诞生以来最大升级,碰一碰、小艺圈选重磅上线

在昨日晚间的原生鸿蒙之夜暨华为全场景新品发布会上,华为原生鸿蒙 HarmonyOS NEXT(5.0)正式发布。 华为官方透露,截至目前,鸿蒙操作系统在中国市场份额占据 Top2 的领先地位,拥有超过 1.1 亿 的代码行和 6…

布隆过滤器:极简存储,高效检索

引言 在海量数据的存储与检索中,如何在保持快速检索的同时,降低内存占用是个巨大的挑战。有没有一种既能快速检索又能节省内存的方案?布隆过滤器(Bloom Filter)就是这样一种数据结构。 布隆过滤器的基本原理 如果我…

Vue.js 学习总结(11)—— Vue3 Hook 函数实战总结

前言 在 Vue 3 中,Hook 函数是一种特殊的函数,用于封装可重用的逻辑和状态管理。Hook 函数允许你在 Vue 组件中提取和复用逻辑,而不是将所有逻辑都放在组件的选项对象中。它们可以帮助你更好地组织代码,提高代码的可维护性和可测…

算法题总结(十九)——图论

图论 DFS框架 void dfs(参数) { if (终止条件) {存放结果;return; }for (选择:本节点所连接的其他节点) {处理节点;dfs(图,选择的节点); // 递归回溯,撤销处理结果 } }深搜三部曲 确认递归函数,参数确认终止条件处理目前搜索节…

JAVA基础:IO流 (学习笔记)

IO流 一,IO流的理解 i : input 输入 o:output 输入 流:方式,传递数据的方式---------相当于生活中的“管道”,“车”,将资源从一个位置,传递到另一个位置 二,IO流的分…

从0开始深度学习(16)——暂退法(Dropout)

上一章的过拟合是由于数据不足导致的,但如果我们有比特征多得多的样本,深度神经网络也有可能过拟合 1 扰动的稳健性 经典泛化理论认为,为了缩小训练和测试性能之间的差距,应该以简单的模型为目标,即模型以较小的维度的…

Qt中使用线程之QConcurrent

QConcurrent可以实现并发,好处是我们可以不用单独写一个类了,直接在类里面定义任务函数,然后使用QtConcurrent::run在单独的线程里执行一个任务 1、定义一个任务函数 2、定义1个QFutureWatcher的对象,使用QFutureWatcher来监测任…

新手直播方案

简介 新手直播方案 ,低成本方案 手机/电脑 直接直播手机软件电脑直播手机采集卡麦电脑直播多摄像机 机位多路采集卡 多路麦加电脑(高成本方案) 直播推流方案 需要摄像头 方案一 :手机 电脑同步下载 网络摄像头 软件&#xff08…

【学术论文投稿】Windows11开发指南:打造卓越应用的必备攻略

【IEEE出版南方科技大学】第十一届电气工程与自动化国际会议(IFEEA 2024)_艾思科蓝_学术一站式服务平台 更多学术会议论文投稿请看:https://ais.cn/u/nuyAF3 目录 引言 一、Windows11开发环境搭建 二、Windows11关键新特性 三、Windows11设计指南 …

小程序开发实战:PDF转换为图片工具开发

目录 一、开发思路 1.1 申请微信小程序 1.2 编写后端接口 1.3 后端接口部署 1.4 微信小程序前端页面开发 1.5 运行效果 1.6 小程序部署上线 今天给大家分享小程序开发系列,PDF转换为图片工具的开发实战,感兴趣的朋友可以一起来学习一下&#xff01…

linux中级(NFS服务器)

NFS:用于在NNIX/Linux主机之间进行文件共享的协议 流程:首先服务端开启RPC服务,并开启111端口,服务器端启动NFS服务,并向RPC注册端口信息,客户端启动RPC,向服务器RPC服务请求NFS端口&#xff0…