news 2026/9/2 9:30:59

进阶-InnoDB引擎-MVCC

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
进阶-InnoDB引擎-MVCC

一、MySQL进阶

“当两个用户同时查看同一份数据,你希望看到的是‘当前状态’,还是‘事务开始时的状态’?”
—— MVCC(多版本并发控制),让数据库在高并发下依然保持“一致性”与“高效性”

为什么需要MVCC?——一场“读写冲突”的危机

在传统数据库中,读操作会阻塞写操作,写操作会阻塞读操作。例如:

  • 事务A:UPDATE orders SET status='shipped' WHERE order_id=100
  • 事务B:SELECT * FROM orders WHERE order_id=100

如果事务B在事务A未提交时执行,会发生什么?

  • 悲观锁:事务B必须等待事务A提交(锁表),导致性能下降
  • 乐观锁:事务B直接读取,但可能读到未提交数据(脏读)

💡2010年,某电商网站因锁表问题导致双11期间响应时间从50ms飙升至500ms,损失超百万!
这就是MVCC诞生的背景在不加锁的情况下,实现高并发读写

1. InnoDB引擎-MVCC

📌 什么是MVCC?

MVCC(Multi-Version Concurrency Control)是一种并发控制机制,它通过保存数据的多个版本,让读操作无需等待写操作,从而实现“读不阻塞写,写不阻塞读”

📌 两种读操作:

类型说明举例是否加锁
当前读(Current Read)读取最新数据(已提交)SELECT ... FOR UPDATE
UPDATE
DELETE
✅ 加锁(X锁)
快照读(Snapshot Read)读取事务开始时的快照SELECT *❌ 不加锁

💡关键点快照读是MVCC的核心,它利用历史版本实现非阻塞读。

MVCC的核心组件:三个隐式字段

InnoDB 通过三个隐藏字段(在表中不可见)实现MVCC

字段作用类型说明
DB_TRX_ID记录最近修改该行的事务ID6字节用于判断行是否对当前事务可见
DB_ROLL_PTR指向Undo Log的指针7字节用于找到历史版本
DB_ROW_ID隐藏的行ID(自增)6字节在索引中作为回表的唯一标

💡为什么需要这些字段?

  • DB_TRX_ID:判断行是否已提交
  • DB_ROLL_PTR:通过Undo Log找到旧版本
  • DB_ROW_ID:在索引中唯一标识行(即使主键未指定)

Undo Log:数据的“时间胶囊”

Undo Log 是 MVCC 的基础,它记录了数据修改前的旧值,用于:

  • 事务回滚
  • MVCC 快照读

📌 Undo Log 两种类型:

类型作用说明
INSERT记录插入的行用于事务回滚(删除时需恢复)
UPDATE记录修改前的旧值用于快照读和回滚(更新时需恢复)

💡Undo Log 的存储
由 InnoDB 的Undo Tablespace管理,可以配置多个 Undo Log 文件(MySQL 5.7+ 支持独立Undo表空间)。

数据版本链:Undo Log 的“链式存储”

当一行数据被多次修改时,Undo Log 会形成版本链

最新版本 → (DB_ROLL_PTR) → 旧版本 → (DB_ROLL_PTR) → 更旧版本 → ... → 初始版本

💡举例

  • 初始:balance=1000
  • 事务1:UPDATE balance=800→ 生成Undo Log(记录1000)
  • 事务2:UPDATE balance=500→ 生成Undo Log(记录800)

版本链:500 → 800 → 1000

ReadView:MVCC的“时间机器”

ReadView是事务开始时生成的快照,它决定了哪些版本对当前事务可见。

📌 ReadView 包含的关键信息:

字段说明
min_trx_id活跃事务最小ID(当前正在执行的事务ID)
max_trx_id活跃事务最大ID(当前正在执行的事务ID上限)
m_ids活跃事务ID列表(当前正在执行的事务ID集合)
def is_visible(trx_id, readview): if trx_id < readview.min_trx_id: # 已提交 return True elif trx_id >= readview.max_trx_id: # 未提交 return False else: # 在活跃事务列表中 if trx_id in readview.m_ids: # 未提交 return False else: # 已提交 return True

💡关键点

  • RR级别(可重复读):事务开始时生成ReadView,后续查询都使用同一ReadView
  • RC级别(读已提交):每次查询都生成新的ReadView

MVCC工作原理:一次事务的“时间穿越”

假设执行:

-- 事务A(ID=100) START TRANSACTION; SELECT * FROM accounts WHERE user_id=1; -- 快照读 UPDATE accounts SET balance=500 WHERE user_id=1; -- 当前读 COMMIT; -- 事务B(ID=101) START TRANSACTION; SELECT * FROM accounts WHERE user_id=1; -- 快照读

📌 MVCC如何工作?

  1. 事务A开始
    • 生成ReadView:min_trx_id=100, max_trx_id=102, m_ids=[100]
    • 执行SELECT:快照读,使用ReadView判断可见性
  2. 事务A执行UPDATE
    • 修改行,生成Undo Log(记录旧值:1000 → 500)
    • DB_TRX_ID更新为100
    • DB_ROLL_PTR指向Undo Log
  3. 事务B执行SELECT
    • 生成ReadView:min_trx_id=101, max_trx_id=102, m_ids=[101]
    • 读取行:DB_TRX_ID=100 < 101→ 可见(值为1000)

🌟效果:事务B在事务A未提交时,读到的是1000(事务A开始时的值),而非500(当前值)。

MVCC在不同隔离级别下的表现

隔离级别快照读可见性规则幻读说明
读未提交不使用MVCC直接读最新数据无MVCC
读已提交使用MVCC每次查询生成新ReadView无法避免不可重复读
可重复读使用MVCC事务开始时生成ReadView通过Next-Key Lock避免幻读
串行化不使用MVCC强制加锁无MVCC

💡为什么RR级别能避免幻读?
InnoDB 在RR级别下使用Next-Key Lock(记录锁 + 间隙锁),在读取时不仅锁住记录,还锁住间隙,防止其他事务插入新数据。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/29 4:30:04

BSHM镜像文档详细,新手也能快速上手

BSHM镜像文档详细&#xff0c;新手也能快速上手 1. 镜像环境说明 为了确保 BSHM (Boosting Semantic Human Matting) 模型在现代硬件环境下稳定运行&#xff0c;本镜像针对 TensorFlow 1.15 的依赖与新一代 GPU 架构进行了深度适配。以下是镜像中预配置的核心组件及其版本信息…

作者头像 李华
网站建设 2026/9/3 0:23:25

Java程序员如何入门AI

文章目录前言&#xff1a;Javaer转AI&#xff0c;没你想的那么难&#xff01;一、先搞懂&#xff1a;Java程序员学AI&#xff0c;核心要学什么&#xff1f;二、环境搭建&#xff1a;3分钟搞定Java AI开发环境2.1 核心依赖清单&#xff08;Maven&#xff09;2.2 开发工具推荐三、…

作者头像 李华
网站建设 2026/9/2 23:27:39

python程序员如何入门AI

文章目录一、为啥Python程序员入门AI最吃香&#xff1f;二、AI入门的3个核心阶段&#xff08;附流程图&#xff09;阶段1&#xff1a;基础铺垫&#xff08;1-2个月&#xff09;1. 必学的数学知识&#xff08;不用啃完高数&#xff09;2. Python数据分析库强化阶段2&#xff1a;…

作者头像 李华
网站建设 2026/8/30 8:38:10

C#程序员如何入门AI

文章目录一、为啥C#程序员学AI不“吃亏”&#xff1f;二、C#入门AI的“三步走”战略&#xff08;附实战代码&#xff09;第一步&#xff1a;基础铺垫&#xff08;不用啃硬骨头&#xff0c;抓核心就行&#xff09;第二步&#xff1a;工具实战&#xff08;用ML.NET写第一个AI程序…

作者头像 李华
网站建设 2026/9/2 21:47:29

元宇宙崩溃实录:缺乏AI压力测试引发的虚拟世界雪崩

—— 一份给软件测试从业者的技术警示录 一、灾难现场&#xff1a;虚拟世界的“切尔诺贝利时刻” &#xff08;模拟事故时间&#xff1a;元历2030年1月15日 16:04&#xff09; 当「寰宇互联」元宇宙平台迎来建网三周年庆典时&#xff0c;1200万用户涌入虚拟主城。16时04分&…

作者头像 李华
网站建设 2026/9/2 21:47:09

基于Springboot+Vue的大学生军训系统设计与实现

前言 &#x1f31e;博主介绍&#xff1a;✌CSDN特邀作者、全栈领域优质创作者、10年IT从业经验、码云/掘金/知乎/B站/华为云/阿里云等平台优质作者、专注于Java、小程序/APP、python、大数据等技术领域和毕业项目实战&#xff0c;以及程序定制化开发、文档编写、答疑辅导等。✌…

作者头像 李华