MVCC 版本链 通俗易懂讲解

MVCC(多版本并发控制)是 InnoDB 存储引擎实现并发读写的核心机制,而版本链就是 MVCC 能工作的 "底层账本"------ 简单说,它是把同一条数据的多次修改记录串联起来的链表,让不同事务能同时读取、修改数据,还不互相干扰。

一、先搞懂:版本链是怎么来的?

InnoDB 的每行数据除了我们自己定义的列(比如 id、name),还藏着两个隐藏字段(核心):

  • DB_TRX_ID:记录最后一次修改这条数据的事务 ID;
  • DB_ROLL_PTR:回滚指针,指向这条数据上一个版本的位置(版本链的 "链扣")。

当数据被修改时,InnoDB 不会直接覆盖原数据,而是做这几步:

  1. 把原数据复制一份,作为 "旧版本" 存到undo 日志(回滚日志)里;
  2. 更新当前行的 DB_TRX_ID 为当前修改事务的 ID;
  3. 把当前行的 DB_ROLL_PTR 指向刚生成的旧版本;
  4. 重复修改的话,新的旧版本会继续链接到上一个旧版本后面,形成 "版本链"。

举个通俗例子:

  • 初始状态:数据行(id=1, name = 张三),DB_TRX_ID=0(无修改),DB_ROLL_PTR=null(无旧版本);
  • 事务 1(ID=100)修改 name 为 "李四":→ 原数据(张三)被存到 undo 日志,成为版本 1;→ 当前行 DB_TRX_ID=100,DB_ROLL_PTR 指向版本 1;
  • 事务 2(ID=200)再修改 name 为 "王五":→ 当前行(李四)被存到 undo 日志,成为版本 2,且版本 2 的 DB_ROLL_PTR 指向版本 1;→ 当前行 DB_TRX_ID=200,DB_ROLL_PTR 指向版本 2;
  • 最终版本链:当前行(王五)→ 版本 2(李四)→ 版本 1(张三)。

二、版本链的核心作用:让读写不冲突

MVCC 会结合事务隔离级别 + Read View(读视图),通过版本链实现:

  1. 读操作(SELECT):不用加锁,直接在版本链里找 "当前事务能看到的最新版本";比如隔离级别是 "可重复读" 时,事务启动后生成 Read View,后续不管其他事务怎么改数据,都只认启动时能看到的版本,避免 "不可重复读"。
  2. 写操作(UPDATE/DELETE):只修改当前版本,旧版本保留在版本链,既不影响读,又能支持事务回滚(回滚时从版本链找回旧数据)。

三、关键细节:版本链和 Read View 的配合

Read View 是事务读取数据时的 "可见性规则",包含 4 个核心值:

  • m_ids:当前活跃的事务 ID 列表;
  • min_trx_id:活跃事务中最小的 ID;
  • max_trx_id:下一个要分配的事务 ID;
  • creator_trx_id:当前事务的 ID。

读取数据时,会遍历版本链,判断每个版本的 DB_TRX_ID 是否符合可见性:✅ 版本的 DB_TRX_ID <min_trx_id:这个版本是 "已提交事务" 改的,可见;❌ 版本的 DB_TRX_ID >= max_trx_id:这个版本是 "未来事务" 改的,不可见;❌ 版本的 DB_TRX_ID 在 m_ids 里:这个版本是 "活跃未提交事务" 改的,不可见;✅ 其他情况:可见。

四、版本链的清理:undo 日志的回收

版本链不是永久存在的 ------ 当没有任何事务需要访问这些旧版本时,InnoDB 的 purge 线程会清理掉没用的 undo 日志(旧版本),避免磁盘占用过大。比如所有事务都已提交,且都不需要回滚到某个旧版本,这个版本就会被清理,版本链也会缩短。

总结

MVCC 版本链的核心逻辑:✅ 数据修改不覆盖,而是生成新版本、链接旧版本,形成版本链;✅ 读操作通过 Read View 在版本链找 "可见版本",不用加锁;✅ 写操作只改当前版本,旧版本支持回滚和并发读;最终实现了 InnoDB 的 "读不加锁、读写不冲突",大幅提升并发性能。

相关推荐
AI-好学者5 小时前
阶段一-图数据库基础与PropertyGraph模型
数据库·rag·knowledge graph·graphrag
其实防守也摸鱼6 小时前
运维--学习阶段问题解答(1)(自测)
linux·运维·服务器·数据库·学习·自动化·命令模式
懒鸟一枚7 小时前
深入理解 Linux 内存、Swap 交换分区与分页机制的关系
java·linux·数据库
龙仔7257 小时前
SQL Server 创建只读账号完整操作(分两种场景:SSMS图形界面 + T-SQL脚本)
数据库·sql·oracle
霁月的小屋7 小时前
生产环境中的事务实践——银行系统上线记(四)
数据库
Database_Cool_7 小时前
AI 应用数据底座首选:阿里云 PolarDB 为大模型 RAG 提供一体化支撑
数据库·阿里云
玖玥拾8 小时前
C# 语言进阶(十五)C# 游戏服务端 MySQL 数据库
服务器·开发语言·网络·数据库·mysql·c#
IvorySQL9 小时前
PG 日报|社区讨论重构 pg_hba 配置文件格式
数据库·人工智能·postgresql·重构·ivorysql
逝水无殇9 小时前
C# 文件的输入与输出详解
开发语言·数据库·后端·c#
罗政10 小时前
PDF 批量合并工具:本地 AI 自动排序、识别正文日期与合同编号
数据库·pdf·php