温馨提示×

温馨提示×

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

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

MVCC为何不用加锁读

发布时间:2026-09-09 21:49:00 来源:亿速云 阅读:94 作者:小樊 栏目:数据库

MVCC(Multi-Version Concurrency Control,多版本并发控制)之所以能实现**“不加锁的读”**,核心原因在于:读操作访问的是数据的历史版本,而不是当前正在被修改的数据,因此不需要阻塞写,也不需要与写操作争抢锁。

下面分层说明。


1. 传统加锁读的问题

在纯锁机制下:

  • 写数据 → 加写锁(X锁)
  • 读数据 → 通常加读锁(S锁)

问题:

  • 读写互斥或读写阻塞
  • 并发度低
  • 容易锁等待、死锁

2. MVCC 的基本思想

MVCC 的核心:

数据不是“被覆盖修改”,而是“保留多个版本”

典型做法:

  • 每行数据有隐藏字段(如事务ID、回滚指针)
  • 修改时:
    • 旧版本保留
    • 新版本生成
  • 读时:
    • 根据事务可见性规则,读取“对自己可见的版本”

3. 为什么读不需要加锁?

关键点 1:读的是“快照/历史版本”

  • 写事务改的是新版本
  • 读事务看到的是启动时的快照版本
  • 两者操作的是不同数据版本

➡ 没有资源冲突
➡ 不需要锁来保护“当前行”


关键点 2:可见性由“事务ID + 快照”决定

例如 InnoDB:

  • 每个事务有 ReadView
  • 判断规则:
    • 该版本是否在本事务开始前已提交
    • 是否被本事务自己修改

满足可见性 → 直接读
不满足 → 沿 undo log 找上一个版本

➡ 控制并发的是逻辑规则,不是锁


关键点 3:读写互不阻塞

  • 写:创建新版本
  • 读:访问旧版本
  • 互不干扰

所以:

MVCC 读 = 无锁读(Lock-Free Read)


4. 那 MVCC 就完全不用锁了吗?

不是,要分清楚:

✅ 读不加锁

  • 普通 SELECT(快照读)
  • 不加任何行锁

❌ 写仍可能加锁

  • UPDATE / DELETE
  • 当前读(SELECT ... FOR UPDATE)
  • 防止写写冲突

5. 一句话总结

MVCC 通过多版本 + 快照可见性,让读操作访问历史数据,从而避免与写操作冲突,因此读不需要加锁。

如果你愿意,我也可以结合 InnoDB 的 undo log + ReadView 或 PostgreSQL 的 xmin/xmax 给你画一个具体例子。

向AI问一下细节

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

AI
助
手