Plantre Plantre
首页
后端
技术
硬件
  • 前端文章

    • HTML
    • CSS
    • JavaScript
  • 技术

    • 技术文档
    • GitHub技巧
    • Nodejs
    • 博客搭建
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

plantre

一个后端开发者
首页
后端
技术
硬件
  • 前端文章

    • HTML
    • CSS
    • JavaScript
  • 技术

    • 技术文档
    • GitHub技巧
    • Nodejs
    • 博客搭建
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 计算机组成原理

  • 操作系统

  • 计算机网络

  • 设计模式

  • Java

  • Spring

  • SpringCloud

  • MySQL

    • MySQL的权限控制
    • 精细权限管制示例
    • localhost和127.0.0.1的区别-MySQL
    • mysql数据类型
    • 当前读和快照读
    • MySQL中MVCC的实现原理
    • MySQL中MVCC具体用了多少个隐藏字段
    • 锁和事务的关系
    • FOR UPDATE锁类型
  • Redis

  • 分布式

  • Zookeeper

  • Dubbo

  • Kafka

  • 数据结构

  • 算法

  • OJ

  • 从道家哲学看计算机?
  • 后端
  • MySQL
plantre
2025-05-06

MySQL中MVCC的实现原理

MySQL中的MVCC(多版本并发控制)是一种通过维护数据历史版本实现高并发读写的技术,其核心实现原理可分为以下五个部分:


一、隐藏字段与版本链

  1. 隐藏字段

    InnoDB为每行数据添加三个隐藏字段: • DB_TRX_ID(6字节):记录最后一次修改该行的事务ID(包括INSERT/UPDATE/DELETE)。

    • DB_ROLL_PTR(7字节):指向Undo Log中该行历史版本的指针,用于构建版本链。

    • DB_ROW_ID(6字节,可选):当表无显式主键时自动生成的隐藏主键,用于聚簇索引。

  2. Undo Log版本链

    • 每次事务修改数据时,旧版本数据会被写入Undo Log,并通过DB_ROLL_PTR形成版本链。例如,事务A(ID=100)插入数据,事务B(ID=200)更新后,版本链结构为:当前数据 → 事务B版本 → 事务A版本。

    • 版本链允许事务回溯历史数据,解决读写冲突时的数据一致性问题。


二、Read View机制

事务执行快照读(如普通SELECT)时生成一致性视图(Read View),包含以下核心属性:

  1. m_ids:当前活跃事务ID列表。
  2. min_trx_id:活跃事务中的最小ID。
  3. max_trx_id:下一个将分配的事务ID(即当前最大事务ID+1)。
  4. creator_trx_id:创建该Read View的事务ID。

三、数据可见性判断规则

通过对比数据行的DB_TRX_ID与Read View属性,确定是否可见:

  1. 规则1:若DB_TRX_ID < min_trx_id,说明该版本在Read View创建前已提交,可见。

  2. 规则2:若DB_TRX_ID ≥ max_trx_id,说明该版本由未来事务生成,不可见。

  3. 规则3:若min_trx_id ≤ DB_TRX_ID < max_trx_id: • 未提交事务:DB_TRX_ID在m_ids中,不可见。

    • 已提交事务:DB_TRX_ID不在m_ids中,可见。

  4. 规则4:若DB_TRX_ID == creator_trx_id,说明是当前事务自身修改的数据,直接可见。

若当前版本不可见,则通过DB_ROLL_PTR回溯Undo Log版本链,直至找到符合条件的历史版本。


四、隔离级别的影响

  1. 读已提交(RC)

    • 每次快照读生成新的Read View,能读到其他事务已提交的最新数据。

    • 示例:事务A第一次读取数据后,事务B提交更新,事务A第二次读取会生成新视图并看到新数据。

  2. 可重复读(RR)

    • 事务首次快照读生成Read View,后续操作复用该视图,保证整个事务期间数据一致性。

    • 示例:事务A第一次读取数据后,事务B修改并提交,事务A第二次读取仍看到旧数据。


五、MVCC的优缺点

优点 缺点
读写不阻塞(非锁定读) 存储开销大(多版本维护)
减少锁竞争与死锁风险 无法完全解决幻读(当前读仍可能触发)
支持高并发场景 依赖后台Purge线程清理旧版本

示例分析

假设事务ID=301的事务查询数据行,当前版本由事务ID=300修改(未提交),版本链包含事务ID=200(已提交)和事务ID=100(已提交)的版本:

  1. Read View的m_ids包含活跃事务ID=200、300、301,min_trx_id=200,max_trx_id=302。
  2. 事务301会跳过事务300的版本(未提交),选择事务100的版本(DB_TRX_ID=100 < min_trx_id),返回旧数据。

通过上述机制,MySQL在保证事务隔离性的同时,实现了高性能的并发读写。具体实现细节在不同版本中可能优化调整,但核心原理保持一致。

编辑 (opens new window)
上次更新: 2025/06/13, 00:51:28
当前读和快照读
MySQL中MVCC具体用了多少个隐藏字段

← 当前读和快照读 MySQL中MVCC具体用了多少个隐藏字段→

最近更新
01
集成loki
07-04
02
TCP的ESTABLISHED是什么意思
06-24
03
安装1panel
06-24
更多文章>
Theme by Vdoing | Copyright © 2025-2025 plantre | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式