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 的 "读不加锁、读写不冲突",大幅提升并发性能。

相关推荐
清风66666638 分钟前
基于单片机的PID调节脉动真空灭菌器上位机远程监控设计
数据库·单片机·毕业设计·nosql·课程设计·期末大作业
酩酊仙人43 分钟前
ABP将ExtraProperties作为查询条件
数据库·postgresql·asp.net
在风中的意志1 小时前
[数据库SQL] [leetcode] 614. 二级关注者
数据库·sql
·云扬·1 小时前
MySQL Group Replication(MGR)核心特性全解析:从事务流程到一致性配置
数据库·mysql
陌路201 小时前
MYSQL事务篇--事务隔离机制的实现
数据库·mysql
oMcLin1 小时前
CentOS 7.9 高负载导致 MySQL 数据库性能下降:内存泄漏与配置优化
数据库·mysql·centos
auspicious航1 小时前
数据库同步技术演进:从备份转储到实时CDC的DBA实战指南
数据库·ffmpeg·dba
SmartRadio1 小时前
物联网云平台数据库选型与搭建全指南(LoRaWAN)
数据库·物联网·lora·lorawan
bst@微胖子2 小时前
CrewAI+FastAPI实现营销战略协助智能体项目
android·数据库·fastapi
小鸡脚来咯2 小时前
MySQL面试题
数据库·mysql