MySql Innodb锁机制

ops/2024/10/20 3:55:26/

锁概述

undo log版本链 + Read View机制实现的MVCC多版本并发控制,可以防止事务并发读写同一数据时出现的脏读+不可重复读+幻读问题。但除脏读+不可重复读+幻读问题外,并发读写同一数据还有脏写问题。就是当多个事务并发更新同一条数据时,此时就可能会出现脏写问题,如下图示:

一.事务A对数据进行操作,将值修改为A;

二.事务B也对该数据进行操作,将值修改为B;

三.接着事务A进行了回滚,将值恢复成NULL;

四.事务B发现数据值B没有了,出现数据不一致;

脏写:一个事务修改了另一个没提交的事务修改过的值,导致数据可能不一致。因为这个没提交的事务有可能会回滚

锁分类

(1)从操作的粒度可分为表级锁、行级锁和页级锁

(2)从操作的类型可分为读锁和写锁

(3)从操作的性能可分为乐观锁和悲观锁

(1)从操作的粒度可分为表级锁、行级锁和页级锁

一.表级锁:每次操作锁住整张表

锁定粒度最大,发生锁冲突概率最高,并发度最低,应用在MyISAM、InnoDB、BDB存储引擎中。

二.行级锁:每次操作锁住一行数据

锁定粒度最小,发生锁冲突的概率最低,并发度最高,应用在InnoDB存储引擎中。

三.页级锁:每次锁定相邻的一组记录

锁定粒度界于表锁和行锁间,开销和加锁时间界于表锁和行锁间。并发度一般,应用在BDB存储引擎中。

(2)从操作的类型可分为读锁和写锁

一.读锁(S锁):共享锁,行级锁

针对同一份数据,多个读操作可以同时进行而不会互相影响。事务A对记录添加了S锁,可以对记录进行读操作,不能做修改。其他事务可以对该记录追加S锁,但是不能追加X锁。要追加X锁,需要等记录的S锁全部释放。

二.写锁(X锁):排它锁,行级锁

当前写操作没有完成前,它会阻断其他事务的写锁和读锁请求。事务A对记录添加了X锁,可以对记录进行读和修改,其他事务不能对记录进行读和修改。

三.IS锁:意向共享锁,表级锁

已加S锁的表肯定会有IS锁,反过来,有IS锁的表不一定会有S锁。

四.IX锁:意向排它锁,表级锁

已加X锁的表肯定会有IX锁,反过来,有IX锁的表不一定会有X锁。

(3)从操作的性能可分为乐观锁和悲观锁

一.乐观锁

一般的实现方式是对记录数据版本进行对比。在数据库表中有一个version字段,根据该字段进行冲突检测。如果有冲突就提示错误信息,所以乐观锁属于代码层面的锁控制。

二.悲观锁

修改一条数据时,为避免被其他事务同时修改,在修改前先锁定。共享锁和排它锁都是悲观锁的不同实现,属于数据库提供的锁机制。

根据加锁的范围,MySQL的锁可以分为:全局锁、表级锁和行级锁三类。

insert 插入流程

针对于事务当中的一笔 insert 操作,过程中的加锁步骤遵循下述流程:

• 1)申请插入意向锁: 本质上是去检查,插入位置所处范围是否存在间隙锁

• 2)唯一键冲突校验: 校验插入记录是否会和已存在记录发生唯一键冲突(Duplicate Key Conflict)

• 3)插入记录并加锁: 若没有唯一键冲突,则插入记录(草稿态),然后对其加行 X Lock

• 4)针对冲突记录加锁: 若发生唯一键冲突,则对引起冲突的行记录左右空隙加间隙锁,并申请该行记录的 S Lock

• 5)冲突记录双重校验:成功后,需要 double check 冲突记录的合法性,是的话返回唯

死锁案例

基于上述流程,下面分享一个因为 INSERT 操作而引发死锁的案例.

在操作开始前,数据表初始的数据状况如下表所示:

具体执行 SQL 如下表,在时刻 3 事务 B 插入 key = n 时因遭遇唯一键冲突,会对记录加左右间隙锁,并因为申请冲突记录的 S Lock 而陷入阻塞;而事务 A 在时刻 4 尝试插入 key = m 时则会因为事务 B 施加的间隙锁而陷入阻塞,最终形成死锁:

事务 A -> 等待事务 B 释放 key = n 的左右间隙锁

事务 B -> 等待事务 A 释放 key = n 的 X Lock

案例延伸探讨 

针对上述死锁案例,我们额外展开探讨一个细节点:

案例中形成死锁的一个重要原因在于,事务 B 遭遇唯一键冲突后,选择先加间隙锁,再申请冲突记录的 S Lock,正是这样的加锁顺序才导致事务 A 后续的 INSERT 操作发生阻塞,最后引起锁资源的循环依赖.

试想一下,事务 B 在唯一键冲突后不申请间隙锁而是仅加冲突记录的行 S Lock(猜想一) ,亦或是把加锁顺序调整为先加行 S Lock,再加间隙锁(猜想二) ,这样是否就能够规避死锁问题呢?

针对猜想一,我们论证一下加间隙锁的必要性.

通过下述 SQL 我们演示一个不加间隙锁而导致的 badcase:

在时刻 3 事务 B 阻塞等待冲突记录行 S Lock,随后时刻 4 事务 A 回滚,因此事务 B 成功获得该行的 S Lock,并且发现行记录已经被删除,判断唯一键冲突问题已解;但与此同时,一个并发执行的事务 C 在此时见缝插针,又插入了一条唯一键相同的记录,这样就会导致事务 B 针对唯一键冲突的校验结果失准.

针对猜想二,其实存在的问题和猜想一是一样的,就是倘若事务 A 回滚,此时没有有效的手段拦截第三方并发事务的插入行为,因此事务 B 才需要先加间隙锁,阻止其他事务的并发插入行为,再进行后续的加行锁和校验操作.

基于 SQL 展示的反例如下:


http://www.ppmy.cn/ops/56071.html

相关文章

ARM/Linux嵌入式面经(十一):地平线嵌入式实习

地平线嵌入式实习面经 1.自我介绍 等着,在给大哥们准备了。 2.spi与iic协议可以连接多个设备吗?最多多少个?通讯时序。 这是几个问题,在回答的时候。不要一问就开口,花几秒钟沉吟思考整理一下自己的思路。 这个问题问了几个点?每个点的回答步骤。 是我的话,我会采用以…

基于Vue的MOBA类游戏攻略分享平台

你好呀,我是计算机学姐码农小野!如果有相关需求,可以私信联系我。 开发语言:Java 数据库:MySQL 技术:Java技术、SpringBoot框架、B/S模式、Vue.js 工具:MyEclipse、MySQL 系统展示 首页 用…

Excel分组求和

目录 1 参考文章2 UNIQUE函数分组3 SUMIF函数分组求和 1 参考文章 1.整体思路:https://blog.csdn.net/Alice_loong/article/details/135580130 2.UNIQUE函数:https://mp.weixin.qq.com/s?__bizMzI3OTcwNDE3OQ&mid2247487044&idx1&sna28108…

服务器被劫持

当服务器被劫持时,可以采取一系列措施来修复和加强安全防护,确保服务器的安全性和数据的完整性。以下是一些建议的步骤和策略:12 确认服务器被劫持:首先需要确认服务器是否被劫持。这可以通过检查服务器的日志、网络流量、以及任…

主数据深度剖析与实际应用

主数据深度剖析与实际应用 想象一下,你正在经营一家跨国连锁咖啡店。每天,全球数千家门店都在使用你的品牌,制作相同的饮品,为客户提供服务。但是,你突然发现一个问题:纽约的"拿铁"和东京的"拿铁"配方似乎不太一样。更糟糕的是,你的线上菜单和实体店菜单显…

华为HCIP Datacom H12-821 卷26

1.单选题 在VRRP中,同一备份组的设备在进行VRRP报文认证时,以下哪一参数不会影响Master设备和Backup设备认证协商结果 A、认证字 B、优先级 C、认证方式 D、VRRP版本 正确答案: B 解析: 优先级只会影响谁是主谁是备,不会影响到他们之间的VRRP协议是否能正常运行。…

Linux动态库的制作

Linux操作系统支持的函数库分为: 静态库,libxxx.a,在编译时就将库编译进可执行程序中。 优点:程序的运行环境中不需要外部的函数库。 缺点:可执行程序大 动态库,又称共享库,libxxx.so&#…

STL——list模拟实现

一、模拟实现源码 #pragma oncenamespace sjx {template <typename T>struct __list_node{__list_node<T>* _next;__list_node<T>* _prev;T _data;__list_node(const T& val T()) :_data(val), _next(nullptr), _prev(nullptr){}};template <typena…