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

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.xdnf.cn/news/716923.html

相关文章:

  • Cangjie 中的值类型与引用类型
  • 设置变体控制两个apk, 一个是有密码,一个是没有密码!
  • 英语写作中“广泛、深入、详细地(的)”extensively、in-depth、at length (comprehensive )的用法
  • 46. Permutations和47. Permutations II
  • Spring Event(事件驱动机制)
  • 力扣面试150题--二叉树的右视图
  • leetcode hot100刷题日记——27.对称二叉树
  • ubuntu系统上运行jar程序输出时间时区不对
  • C#实现单实例应用程序:确保程序唯一运行实例
  • 算法第32天|509. 斐波那契数、70. 爬楼梯、746. 使用最小花费爬楼梯
  • 构筑电网“无形防线”: 防外破告警在线监测服务系统
  • 如何批量给局域网内网里的电脑发送信息
  • STM32 HAL库函数学习 GPIO篇
  • 【Redis】RDB和AOF混合使用
  • Java求职面试:从核心技术到AI与大数据的全面考核
  • 网络编程之网络编程预备知识
  • Python对接GPT-4o API接口:聊天与文件上传功能详解
  • 人工智能浪潮下,制造企业如何借力DeepSeek实现数字化转型?
  • cutlass学习教程
  • Security
  • Coze Space的分享体验:基于Y模型分析法的深入剖析
  • 交通违法拍照数据集,可识别接打电话,不系安全带的行为,支持YOLO,COCO JSON,VOC XML格式的标注数据集 最高正确识别率可达88.6%
  • window安装nginx
  • PostgreSQL查询一个表的数据
  • AI预测3D新模型百十个定位预测+胆码预测+去和尾2025年5月29日第92弹
  • N2语法 逆接
  • Python应用while嵌套循环
  • 嵌入式学习笔记 - freeRTOS 阻塞延时的实现机制,同时避免在中断中扫描停留
  • 2025音频传输模块全球选购指南:高品质音频体验的品牌之选
  • 民锋视角下的资产配置策略优化与风险评估模型探索