MySQL MVVC多版本并发控制如何实现

来源:建站技术作者:半夏头衔:草根站长
导读:本期聚焦于小伙伴创作的《MySQL MVVC多版本并发控制如何实现》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《MySQL MVVC多版本并发控制如何实现》有用,将其分享出去将是对创作者最好的鼓励。

MySQL的MVVC多版本并发控制是InnoDB存储引擎实现事务隔离级别的核心技术,它通过在数据行上维护多个版本的历史记录,让读写操作不需要互相阻塞,从而提升数据库的并发性能,主要应用于可重复读和读已提交两种事务隔离级别。

MVVC的核心组成部分

1. 行记录的隐藏字段

InnoDB引擎为每一行记录添加了三个隐藏字段,是MVVC实现的基础:

  • trx_id:记录最后一次修改该行的事务ID,每次事务对行进行修改时,都会更新这个字段为当前事务的ID。
  • roll_pointer:回滚指针,指向该行上一个版本的undo log记录,所有历史版本通过这个指针串联成版本链。
  • row_id:当表没有定义主键时自动生成的隐藏主键,和MVVC逻辑关联度较低。

2. undo log版本链

当事务对一行记录进行修改时,不会直接覆盖原有数据,而是先将旧版本数据写入undo log,再通过roll_pointer指针将新旧版本关联起来,形成一条从最新版本到最旧版本的链表,这就是版本链。事务读取数据时,会根据规则从版本链中匹配符合可见性的版本。

3. Read View(一致性读视图)

Read View是事务执行快照读时生成的一个数据结构,用来判断版本链中的哪个版本对当前事务可见,主要包含四个核心属性:

属性名含义
m_ids生成Read View时,当前系统中所有活跃的事务ID列表
min_trx_idm_ids中的最小事务ID
max_trx_id生成Read View时,系统下一个将要分配的事务ID
creator_trx_id生成该Read View的事务自己的ID

MVVC的版本可见性判断规则

当事务需要读取一行记录时,会从版本链的最新版本开始遍历,按照以下规则判断每个版本是否可见:

  • 如果版本的trx_id等于creator_trx_id,说明该版本是当前事务自己修改的,可见。
  • 如果版本的trx_id小于min_trx_id,说明修改该版本的事务在生成Read View时已经提交,可见。
  • 如果版本的trx_id大于等于max_trx_id,说明修改该版本的事务是在生成Read View之后才开启的,不可见。
  • 如果版本的trx_id在min_trx_id和max_trx_id之间,需要判断trx_id是否在m_ids列表中:如果在,说明修改该版本的事务还未提交,不可见;如果不在,说明该事务已经提交,可见。

如果当前版本不可见,就顺着roll_pointer指针找上一个版本,重复上述判断,直到找到可见的版本或者遍历完所有版本。

不同隔离级别下的MVVC实现差异

读已提交隔离级别

在读已提交级别下,事务每次执行快照读时都会生成一个新的Read View。这意味着如果其他事务在本次事务两次查询之间提交了修改,第二次查询生成的Read View会包含新的已提交事务,从而能读到最新的已提交数据,因此该级别无法避免不可重复读和幻读。

可重复读隔离级别

在可重复读级别下,事务只在第一次执行快照读时生成Read View,后续所有的快照读都会复用这个Read View。因此即使其他事务在期间提交了修改,当前事务的Read View不会变化,读取到的数据始终和第一次查询时一致,从而实现了可重复读,同时通过Next-Key Lock机制配合MVVC可以避免大部分幻读问题。

代码示例演示MVVC运作

下面通过两个并发事务的示例,演示可重复读级别下MVVC的运作逻辑,假设当前有一张用户表user,初始有一条数据:

-- 初始数据
CREATE TABLE user (
    id INT PRIMARY KEY,
    name VARCHAR(20)
) ENGINE=InnoDB;
INSERT INTO user VALUES (1, '张三');

事务A(事务ID为100)和事务B(事务ID为101)的执行顺序如下:

-- 事务A 开启事务
START TRANSACTION;
-- 事务A 第一次查询,此时生成Read View,m_ids为[100,101],min_trx_id=100,max_trx_id=102,creator_trx_id=100
SELECT * FROM user WHERE id=1; -- 结果为 (1, '张三')

-- 事务B 开启事务,修改数据并提交
START TRANSACTION;
UPDATE user SET name='李四' WHERE id=1;
COMMIT;

-- 事务A 第二次查询,复用第一次的Read View
SELECT * FROM user WHERE id=1; -- 结果仍然为 (1, '张三'),因为事务B的trx_id=101在m_ids中,版本不可见,顺着版本链找到trx_id为初始事务的旧版本
-- 事务A 提交
COMMIT;

上述示例中,事务A两次查询的结果一致,就是MVVC在可重复读级别下的典型表现。如果是读已提交级别,事务A第二次查询时会生成新的Read View,此时事务B已经提交,m_ids中不再包含101,因此会读到更新后的李四数据。

MVVC的适用场景

MVVC主要适用于普通的快照读场景,也就是不加锁的SELECT查询。如果是当前读(比如SELECT ... FOR UPDATE、UPDATE、DELETE语句),InnoDB会采用锁机制来保证数据一致性,不会使用MVVC的版本判断逻辑。开发者在实际开发中可以根据业务需求选择合适的查询方式,平衡并发性能和数据一致性要求。

MySQLMVVC多版本并发控制事务隔离级别修改时间:2026-06-24 14:16:01

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。