当前位置: 首页 > article >正文

MVCC(多版本并发控制)机制

1. MVCC(多版本并发控制)机制

MVCC 的核心就是 Undo Log+ Read View,“MV”就是通过 Undo Log 来保存数据的历史版本,实现多版本的管理,“CC”是通过 Read View 来实现管理,通过 Read View 原则来决定数据是否显示。同时针对不同的隔离级别,Read View 的生成策略不同,也就实现了不同的隔离级别。

1.1. MVCC的概念

MVCC的概念:

MVCC(Multiversion Concurrency Control,多版本并发控制)是一种基于乐观锁思想实现事务隔离的技术,核心是:

  • 保存数据的多个版本(历史快照)
  • 读取时通过版本号判断是否可见,无需加锁

MVCC解决的问题:

  1. 读写之间阻塞的问题,通过 MVCC 可以让读写互相不阻塞,即读不阻塞写,写不阻塞读,这样就可以提升事务并发处理能力。
  2. 降低了死锁的概率。这是因为 MVCC 采用了乐观锁的方式,读取数据时并不需要加锁,对于写操作,也只锁定必要的行。
  3. 解决一致性读的问题。一致性读也被称为快照读,当我们查询数据库在某个时间点的快照时,只能看到这个时间点之前事务提交更新的结果,而不能看到这个时间点之后事务提交的更新结果。

快照读vs当前读:

类型

描述

是否加锁

快照读

读取的是历史版本(不加锁)

当前读

读取的是最新版本数据(加锁)

快照读示例:

SELECT * FROM player WHERE ...  -- 快照读(不加锁)

当前读示例:

SELECT * FROM player LOCK IN SHARE MODE;  -- 加锁读
UPDATE player SET ...                     -- DML 操作

1.2. MVCC 的实现原理(InnoDB中)

当查询一条记录的时候,系统如何通过多版本并发控制技术找到它:

  1. 首先获取事务自己的版本号,也就是事务 ID;
  2. 获取 Read View;
  3. 查询得到的数据,然后与 Read View 中的事务版本号进行比较;
  4. 如果不符合 Read View 规则,就需要从 Undo Log 中获取历史快照;
  5. 最后返回符合规则的数据。

InnoDB中存储记录的多个版本的方法:

1. 事务版本号(Transaction ID)

  • 每个事务启动时,InnoDB 分配唯一的递增事务 ID。
  • 用于判断操作先后顺序。

2. 行记录的隐藏列

InnoDB 的叶子段存储了数据页,数据页中保存了行记录,而在行记录中有一些重要的隐藏字段。

InnoDB 为每条记录维护隐藏字段:

字段名

含义

db_row_id

隐藏行 ID,用于创建聚集索引

db_trx_id

最后修改该行记录的事务 ID

db_roll_ptr

回滚指针,指向 Undo Log 的位置

3. Undo Log(撤销日志)

  • 用于保存行记录的历史版本。
  • 以链表形式连接历史版本,支持回滚和快照读取。

Read View 的作用与原理

1. Read View 定义:

  • 一个事务启动时生成的视图,记录当前活跃事务的 ID 列表。
  • 用于判断某行记录是否对当前事务可见。

2. Read View主要字段:

字段

含义

trx_ids

当前活跃事务 ID 集合(未提交事务)

low_limit_id

trx_ids 中最大事务 ID

up_limit_id

trx_ids 中最小事务 ID

creator_trx_id

当前事务 ID(即创建此 Read View 的事务)

3. Read View的可见性判断规则:

  • T < up_limit_id → 可见(提交早)
  • T > low_limit_id → 不可见(提交晚)
  • up_limit_id < T < low_limit_id
  • T ∈ trx_ids → 不可见(事务未提交)
  • T ∉ trx_ids → 可见(事务已提交)

4. 事务隔离级别下 Read View 行为

隔离级别

Read View 获取频率

是否避免不可重复读

读已提交

每次 SELECT 创建新 Read View

可重复读

第一次 SELECT 后复用 Read View

        1. 在隔离级别为读已提交(Read Commit)时,一个事务中的每一次 SELECT 查询都会获取一次 Read View。

如果 Read View 不同,就可能产生不可重复读或者幻读的情况。

        2. 当隔离级别为可重复读的时候,就避免了不可重复读,这是因为一个事务只在第一次 SELECT 的时候会获取一次 Read View,而后面所有的 SELECT 都会复用这个 Read View。

1.3. InnoDB解决幻读的方法

在可重复读的情况下,InnoDB 可以通过 Next-Key 锁 +MVCC 来解决幻读问题。

出现幻读的原因是在读已提交的情况下,InnoDB 只采用记录锁(Record Locking)。

InnoDB 三种行锁的方式:

  • 记录锁:针对单个行记录添加锁。
  • 间隙锁(Gap Locking):可以帮我们锁住一个范围(索引之间的空隙),但不包括记录本身。采用间隙锁的方式可以防止幻读情况的产生。
  • Next-Key 锁:帮我们锁住一个范围,同时锁定记录本身,相当于间隙锁 + 记录锁,可以解决幻读的问题。

在隔离级别为可重复读时,InnoDB 会采用 Next-Key 锁的机制,帮我们解决幻读问题。

http://www.lryc.cn/news/2392734.html

相关文章:

  • Mac M1 安装 ffmpeg
  • Spring框架学习day3--Spring数据访问层管理(IOC)
  • 什么是集群(Cluster)?如何保证集群的高可用性?
  • React从基础入门到高级实战:React 核心技术 - 动画与过渡效果:提升 UI 交互体验
  • 重读《人件》Peopleware -(13)Ⅱ 办公环境 Ⅵ 电话
  • Free2AI:企业智能化转型的加速器
  • Python训练营打卡Day40
  • 制作一款打飞机游戏63:自动保存
  • 使用animation.css库快速实现CSS3旋转动画效果
  • 基于NetWork的类FNAF游戏DEMO框架
  • 湖北理元理律师事务所:债务优化中的生活保障实践
  • golang连接sm3认证加密(app)
  • 【Zephyr 系列 2】用 Zephyr 玩转 Arduino UNO / MEGA,实现串口通信与 CLI 命令交互
  • AIS常见问题解答(AIS知识补充)
  • 基于Matlab实现指纹识别系统
  • Windows10下搭建sftp服务器(附:详细搭建过程、CMD连接测试、连接失败问题分析解决等)
  • Vue3中Element-Plus中el-input及el-select 边框样式
  • vue + ant-design + xlsx 实现Excel自定义模板导入功能
  • SAP saml2 元数据 HTTP 错误
  • 知识课堂|sCMOS相机可编程快门模式解析
  • 数据结构之栈:原理与常用方法
  • 在React框架中使用Braft Editor集成Table表格的详细教程
  • 跳动的爱心
  • gbase8s数据库+mybatis问题记录
  • 实现安卓端与苹果端互通的方案多种多样,以下是一些主要的方案
  • SpringBoot开发——Spring Boot异常处理全攻略:五大方案实战对比
  • React-props
  • 【C++篇】list模拟实现
  • Oracle exist
  • 带sdf 的post sim 小结