08.MVCC原理 ✅常识原理
MVCC(多版本并发控制)是数据库系统中的一种乐观并发控制方式,通过可见性算法实现高效的并发访问。
MVCC的两种读形式包括快照读(无需加锁,读取当前事务可见版本)和当前读(读取最新版本,涉及增删改操作)。
MVCC通过隐藏字段(如RowID、事务ID、回滚指针)和undo log(记录事务操作的日志)来实现。
可见性算法通过比较事务ID和系统活跃事务列表判断数据对当前事务的可见性,从而避免了锁的使用带来的性能问题。
# 01.MVCC原理
# 1、MVCC概述
- MySQL 的 MVCC(多版本并发控制)机制用于
解决读写冲突,保证事务的隔离性 - 其底层原理主要基于
每行数据的版本管理和事务的快照隔离 - 每当对行数据进行修改时,MySQL 会生成一个新的版本,而不是直接修改原有数据
- 这是通过在每行数据中增加两个隐藏列来实现的
- 一个是
trx_id,表示修改该行的事务 ID - 另一个是
delete_flag,用于标记行是否已被删除
- 一个是
# 2、快照读和当前读
快照读:- 读取的只是当前事务的可见版本,不用加锁
- 而你只要记住 简单的 select 操作就是快照读(select * from table where id = xxx)
当前读:- 读取的是当前最新版本,比如 特殊的读操作,更新/插入/删除操作
- 当前读会被其他事务的写操作阻塞,确保读取的是最新的数据状态
# 3、MVCC 实现原理
# 1)MVCC隐藏字段
- MVCC 使用了“三个隐藏字段”来实现版本并发控制
| RowID | DB_TRX_ID | DB_ROLL_PTR | id | name | password |
|---|---|---|---|---|---|
| 自动创建的id | 事务id | 回滚指针 | id | name | password |
RowID:隐藏的自增ID,当建表没有指定主键,InnoDB会使用该RowID创建一个聚簇索引DB_TRX_ID:最近修改(更新/删除/插入)该记录的事务IDDB_ROLL_PTR:回滚指针,指向这条记录的上一个版本删除标记(Delete Flag):指示该行是否已被逻辑删除
# 2)MVCC 的 可见性算法
undoLog: 事务的回滚日志,是 可见性算法 的非常重要的部分,分为两类insert undo log:- 事务在
插入新记录产生的undo log,当事务提交之后可以直接丢弃
- 事务在
update undo log:事务在进行
update 或者 delete 的时候产生的 undo log,在快照读的时候还是需要的,所以不能直接删除只有当系统没有比这个log
更早的read-view了的时候才能删除ps:所以长事务会产生很多老的视图导致undo log无法删除 大量占用存储空间
read-view: 读视图,是MySQL秒级创建视图的必要条件- 比如一个事务在进行 select 操作(快照读)的时候会创建一个 read-view ,这个read-view 其实只是三个字段
alive_trx_list:read-view生成时所有活跃事务 ID 列表up_limit_id:记录上面的 alive_trx_list 中的最小事务 IDlow_limit_id:目前已出现的事务ID的最大值 + 1(表示将来可能出现的事务的下限)
可见性算法规则指的是当前事务对特定数据记录的可见性判断当前事务:是正在执行某些操作的事务,它有自己的事务 IDDB_TRX_ID:
最后一次对特定数据行进行修改的事务的 ID(插入、更新或删除操作)
1)
比 读视图最小事务ID 还小(可见)- 比较
DB_TRX_ID(最近修改事务ID)与up_limit_id(前读视图中 最小事务 ID) - 如果
最近修改事务ID≤最小事务 ID,当前事务可以看到该记录(否则,进入下一步判断)
- 比较
2)
比 读视图当时最大事务ID还大(不可见)- 比较
DB_TRX_ID最近修改事务ID)与low_limit_id(前读视图中 事务ID的最大值 + 1) - 如果
最近修改事务ID≥事务ID的最大值 + 1,则当前事务无法看到该记录(否则,进入下一步判断)
- 比较
3)
如果最近修改事务已经完成提交(可见)- 判断
DB_TRX_ID(最近修改事务ID)是否在活跃事务的数组中 - 如果在活跃事务列表中,则该记录尚未提交,对当前事务不可见
- 如果不在,则该记录已提交,当前事务可见
- 判断

上次更新: 2025/4/29 17:38:19