温馨提示×

温馨提示×

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

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

MVCC在事务中如何工作

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

MVCC(Multi-Version Concurrency Control,多版本并发控制)是现代数据库(如 MySQL InnoDB、PostgreSQL、Oracle 等)实现高并发事务的重要机制。它的核心思想是:读不加锁、写不阻塞读,通过保存数据的多个版本来实现事务隔离。

下面以MySQL InnoDB为例,系统说明 MVCC 在事务中是如何工作的。


一、MVCC 依赖的核心结构

1. 隐藏字段(每行数据都有)

InnoDB 每行记录包含:

  • DB_TRX_ID:最近修改该行的事务 ID
  • DB_ROLL_PTR:回滚指针,指向 undo log 中的旧版本
  • DB_ROW_ID(可选):行标识

2. Undo Log(回滚日志)

  • 每次更新都会生成旧版本数据
  • 旧版本通过 roll_ptr 串成版本链

3. Read View(读视图)

事务在第一次查询时生成,用于判断:

  • 哪些版本“对我可见”
  • 哪些版本“对我不可见”

二、事务如何进行 MVCC 读

示例场景

事务A: BEGIN;        -- trx_id = 100
事务B: BEGIN;        -- trx_id = 200

事务B: UPDATE user SET age=30 WHERE id=1;
事务B: COMMIT;

事务A: SELECT * FROM user WHERE id=1;

执行过程

  1. 事务 A 生成 Read View
  2. 读取 id=1 的行:
    • 当前版本 trx_id = 200
    • Read View 发现 200 已提交 ✅ → 可见
  3. 如果事务 B 未提交:
    • 当前版本不可见
    • 沿 roll_ptr 找 undo log 中的旧版本
    • 直到找到对 A 可见的版本

✅ 读到的不是“最新数据”,而是“事务开始时该看到的数据”


三、Read View 的可见性规则(核心)

Read View 包含:

  • m_ids:当前活跃事务 ID 列表
  • min_trx_id:最小活跃事务 ID
  • max_trx_id:下一个将分配的事务 ID
  • creator_trx_id:创建该 Read View 的事务

判断规则

数据版本 trx_id 可见性
< min_trx_id ✅ 可见(已提交)
> max_trx_id ❌ 不可见(未来事务)
在 m_ids 中 ❌ 不可见(未提交)
= creator_trx_id ✅ 可见(自己改的)
其他 ✅ 可见

四、不同隔离级别下的 MVCC 行为

隔离级别 Read View 生成时机 特点
READ COMMITTED 每次 SELECT 都生成 看到已提交最新数据
REPEATABLE READ 第一次 SELECT 生成 可重复读(MySQL 默认)
READ UNCOMMITTED 不用 MVCC 直接读最新
SERIALIZABLE 退化成锁 不使用 MVCC

✅ MySQL 的 REPEATABLE READ 靠 MVCC 实现,不需要锁读


五、MVCC 与写操作

  • UPDATE / DELETE
    • 旧版本写入 undo log
    • 新版本 trx_id = 当前事务
  • 写写冲突
    • 使用 行锁 + 事务机制
    • MVCC 只解决“读写不阻塞”

六、MVCC 的优点与代价

优点

  • 读不阻塞写,写不阻塞读
  • 高并发性能好
  • 实现可重复读

代价

  • 存储空间增加(多版本)
  • 需要 purge 线程清理过期版本

七、一句话总结

MVCC 通过“数据多版本 + 事务视图(Read View)”让每个事务看到自己该看到的数据快照,从而实现无锁读和高并发。

如果你愿意,我也可以用时序图 / 对比 PostgreSQL MVCC / 面试题角度再讲一遍。

向AI问一下细节

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

AI
助
手