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 在高并发场景下,既能保证事务隔离性,又能避免读操作的锁阻塞,大幅提升了数据库性能。

相关推荐
Pluto_CSND2 小时前
Java中的静态代理与动态代理(Proxy.newProxyInstance)
java·开发语言
不光头强2 小时前
Spring框架的事务管理
数据库·spring·oracle
百***46453 小时前
Java进阶-在Ubuntu上部署SpringBoot应用
java·spring boot·ubuntu
serve the people3 小时前
Prompts for Chat Models in LangChain
java·linux·langchain
一叶飘零_sweeeet3 小时前
不止于 API 调用:解锁 Java 工具类设计的三重境界 —— 可复用性、线程安全与性能优化
java·工具类
惊讶的猫4 小时前
LSTM论文解读
开发语言·python
獨枭4 小时前
C# 本地项目引用失效与恢复全攻略
开发语言·c#·visual studio
百***92024 小时前
【MySQL】MySQL库的操作
android·数据库·mysql
q***76664 小时前
Spring Boot 从 2.7.x 升级到 3.3注意事项
数据库·hive·spring boot
信仰_2739932435 小时前
Redis红锁
数据库·redis·缓存