MVCC(多版本并发控制)

MVCC是 InnoDB 实现非阻塞读的核心技术,其核心思想是:允许多个事务同时读取同一行数据而不相互阻塞,每个事务只能看到自身可见的数据版本。即使其他事务在期间修改了数据,当前事务仍能看到事务启动时的数据状态,从而在无锁情况下实现高效并发。

一、Read View:控制可见性的快照视图

Read View 是 MVCC 实现版本可见性判断的关键机制,它本身不存储数据,仅记录判断快照可见性的元信息,配合undo log中保存的历史版本数据,共同决定事务能看到哪个版本的记录。

1. Read View 的四个核心字段
  • m_ids:生成 Read View 时,当前所有活跃(未提交)事务的 ID 集合。

  • min_trx_id:m_ids 集合中的最小事务 ID(若 m_ids 为空,则等于 max_trx_id)。

  • max_trx_id:生成 Read View 时,系统下一个待分配的事务 ID(即当前全局最大事务 ID+1,非 m_ids 中的最大值)。

  • creator_trx_id:生成当前 Read View 的事务自身 ID(即当前查询事务的 ID)。

2. 数据版本的基础:隐藏列

InnoDB 的聚簇索引记录中包含两个隐藏列,用于支持版本链管理:

  • trx_id:记录最后修改该数据的事务 ID(事务修改数据时写入)。

  • roll_pointer:指向 undo log 中该记录的上一个版本,形成版本链(每次修改都会生成新版本,旧版本存入 undo log),当某版本对当前 Read View 不可见时,存储引擎会沿 roll_pointer 在 undo log 中回溯,直到找到对当前快照可见的版本。

二、隔离级别与 Read View 的生成时机

读已提交(RC)和可重复读(RR)隔离级别的核心差异,在于 Read View 的生成时机不同,这直接影响事务看到的数据版本:

  • **读已提交(RC):**每次执行快照读时都会重新生成 Read View。因此,同一事务中多次查询可能看到不同的提交版本(可能出现 "不可重复读")。

  • **可重复读(RR):**事务中第一次执行快照读时生成 Read View,后续查询复用该 Read View。因此,同一事务中多次查询看到的是同一快照,避免 "不可重复读"。

三、数据版本的可见性判断逻辑

基于 Read View 的字段,事务访问记录时,通过比较记录的trx_id与 Read View 字段,判断该版本是否可见(自身事务修改的版本始终可见):

1.若 trx_id == creator_trx_id:

当前事务自己写的版本,可见

2.若 trx_id < min_trx_id:

该版本由 Read View 生成前已提交的事务创建,可见。

3.若 trx_id >= max_trx_id:

该版本由 Read View 生成后才启动的事务创建,不可见。

4.若 min_trx_id ≤ trx_id < max_trx_id:

若 trx_id 在 m_ids 中:生成该版本的事务仍活跃(未提交),不可见。

若 trx_id 不在 m_ids 中:生成该版本的事务已提交,可见。

四、总结

MVCC 通过版本链(基于 undo log 和隐藏列)和 Read View(可见性判断规则),实现了并发事务对数据的非阻塞读。其中,Read View 的四个字段定义了 "可见性边界",而不同隔离级别通过控制 Read View 的生成时机,平衡了并发性能与数据一致性(如 RR 的 "重复读" 与 RC 的 "实时读")。这种机制让 InnoDB 在高并发场景下,既能保证事务隔离性,又能避免读操作的锁阻塞,大幅提升了数据库性能。

相关推荐
此生只爱蛋5 分钟前
【Redis】主从复制
数据库·redis
寻寻觅觅☆23 分钟前
东华OJ-基础题-104-A == B ?(C++)
开发语言·c++
马猴烧酒.23 分钟前
【面试八股|JAVA多线程】JAVA多线程常考面试题详解
java·服务器·数据库
lightqjx33 分钟前
【C++】unordered系列的封装
开发语言·c++·stl·unordered系列
天天爱吃肉82181 小时前
跟着创意天才周杰伦学新能源汽车研发测试!3年从工程师到领域专家的成长秘籍!
数据库·python·算法·分类·汽车
zh_xuan1 小时前
kotlin lazy委托异常时执行流程
开发语言·kotlin
大巨头1 小时前
sql2008 数据库分页语句
数据库
sino爱学习1 小时前
高性能线程池实践:Dubbo EagerThreadPool 设计与应用
java·后端
m0_715575341 小时前
使用PyTorch构建你的第一个神经网络
jvm·数据库·python
阿猿收手吧!1 小时前
【C++】string_view:高效字符串处理指南
开发语言·c++