温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

MVCC如何避免脏读

发布时间:2026-07-15 04:53:48 来源:亿速云 阅读:95 作者:小樊 栏目:数据库

MVCC(Multi‑Version Concurrency Control,多版本并发控制)通过为数据维护多个历史版本,并配合一致性读视图(Read View)来避免脏读。下面从概念和流程两个层面说明它是如何做到的。


一、什么是脏读

脏读:一个事务读到了另一个事务尚未提交的数据。
如果那个事务随后回滚,读到的数据就是“脏”的、不存在的数据。


二、MVCC 的核心思想

读不加锁,写不阻塞读,通过版本判断可见性。

MVCC 的关键机制包括:

  1. 数据多版本
  2. 事务 ID(trx_id)
  3. 回滚段 / undo log
  4. 一致性读视图(Read View)

三、MVCC 如何避免脏读(以 InnoDB 为例)

1️⃣ 每一行记录都有隐藏字段

InnoDB 中,每一行记录包含:

  • trx_id:最后一次修改该行的事务 ID
  • roll_pointer:指向 undo log(历史版本)

2️⃣ 事务开启时创建 Read View

当一个事务执行**一致性读(普通 SELECT)**时:

  • 会生成一个 Read View
  • Read View 记录:
    • 当前活跃的事务 ID 列表
    • 最小活跃事务 ID
    • 下一个将被分配的事务 ID

3️⃣ 判断数据版本是否可见(关键步骤)

当读取一行数据时:

  1. 从最新版本开始
  2. 比较该版本的 trx_id 与 Read View
  3. 判断规则(简化版):
情况 是否可见
trx_id < 最小活跃事务 ID ✅ 可见(已提交)
trx_id 在活跃事务列表中 ❌ 不可见(未提交)
trx_id ≥ 下一个事务 ID ❌ 不可见(未来事务)
否则 ✅ 可见

如果当前版本不可见:

  • 通过 roll_pointer 找 undo log 中的上一个版本
  • 再次判断可见性
  • 直到找到一个可见版本或遍历完

4️⃣ 为什么不会脏读?

  • 未提交事务的修改,其 trx_id 一定在 Read View 的活跃事务列表中
  • 当前事务在判断可见性时:
    • 会认为这些版本 不可见
    • 自动跳过,读取更早的已提交版本
  • 因此:

    永远不会读到其他事务未提交的数据


四、对比:MVCC vs 锁

机制 是否避免脏读 特点
加锁读(SELECT FOR UPDATE) ✅ 阻塞写
MVCC 一致性读 ✅ 非阻塞、高性能
读未提交(Read Uncommitted) ❌ 直接读最新数据

五、一句话总结

MVCC 通过 Read View 判断数据版本的可见性,只读取“已经提交且对当前事务可见”的版本,从而天然避免脏读。

如果你愿意,我也可以:

  • 用 时间线图演示一次 MVCC 读取过程
  • 对比 RC 和 RR 隔离级别下 Read View 的差异
  • 结合 undo log 讲一个完整示例
向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI
助
手