MVCC实现过程

什么是MVCC

MVCC,多版本并发控制。

通过保存数据的历史版本,根据比较数据的版本号来决定数据的是否显示,在不需要加读锁的情况就能达到事务的隔离效果,最终可以在读取数据的时候可以同时进行修改,修改数据时候可以同时读取,极大的提升了事务的并发性能。

部分名词解释

名词解释
事务版本号一个事务开启后都会获得一个自增长的事务的ID,由此判断先后顺序
trx_id记录操作该数据事务的事务ID
roll_pointer相当于一个指针,指向回滚段的undo日志
row_id单调递增的行ID,不是必需的,占用6个字节
undo log回滚日志,用于记录数据被修改前的信息
版本链多个事务并行操作某一行数据时,不同事务对该行数据的修改会产生多个版本,然后通过回滚指针,连成一个链表
快照读读取的是记录数据的可见(有旧版本)版本(不加锁)
当前读读取的是记录数据的最新版本(显式加锁)
Read View执行SQL语句时产生的读视图,判断当前事务可见哪个版本的数据
m_ids当前系统活跃未提交的所有事务ID(列表)
up_limit_id生成Read View时,当前系统中活跃的读写事务中最小的事务id
low_limit_id生成Read View时,系统中应该分配给下一个事务的id值
creator_trx_id创建当前Read View的事务ID

MVCC实现流程

在这里插入图片描述

说明一下Read View的匹配规则。

1)如果数据事务ID trx_id < up_limit_id,表明生成该版本的事务在生成Read View前,已经提交(因为事务ID是递增的),所以该版本可以被当前事务访问。

2)如果trx_id >= low_limit_id,表明生成该版本的事务在生成ReadView后才生成,所以该版本不可以被当前事务访问。

3)如果 up_limit_id <= trx_id < low_limit_id,需要分3种情况讨论

(1)如果m_ids包含trx_id,则代表Read View生成时刻,这个事务还未提交,但是如果数据的trx_id等于creator_trx_id的话,表明数据是自己生成的,因此是可见的。
(2)如果m_ids包含trx_id,并且trx_id不等于creator_trx_id,则Read View生成时,事务未提交,并且不是自己生产的,所以当前事务也是看不见的;
(3)如果m_ids不包含trx_id,则说明你这个事务在Read View生成之前就已经提交了,修改的结果,当前事务是能看见的。
<think>好的,用户想了解MVCC实现原理,需要详细解释。我需要结合之前提供的引用资料来组织回答。首先,确定MVCC的基本概念,然后分点说明实现机制,比如隐式字段、undo log、Read View等。还要注意引用标注的正确性,确保每个部分都有对应的引用来源。同时,要检查是否有用户不可见的系统级指令需要遵守,比如LaTeX格式和结构要求。可能还需要生成相关问题,但放在最后。用户可能对事务隔离级别和MVCC的关系不太清楚,所以需要明确说明。另外,需要对比当前读和快照读,这也是用户可能感兴趣的点。确保回答结构清晰,分步骤讲解,避免技术术语堆砌,让用户容易理解。</think>### MVCC实现原理详解 MVCC(多版本并发控制)是数据库管理系统中实现非阻塞读操作的核心技术,通过数据多版本管理实现读写操作并发执行。其实现依赖三个核心组件: #### 一、基础存储结构 1. **隐式字段** 每条记录包含三个系统字段(用户不可见): - `DB_TRX_ID`(6字节):记录最后一次修改该数据的事务ID $$示例值:事务100修改后的数据\ DB\_TRX\_ID=100$$ - `DB_ROLL_PTR`(7字节):指向undo log的回滚指针[^3] - `DB_ROW_ID`(6字节):隐藏自增主键(当表无主键时生成)[^2] 2. **版本链构建** 通过回滚指针形成的版本链结构: ```plaintext 当前记录 ← undo log记录v3 ← undo log记录v2 ← undo log记录v1 ``` #### 二、核心运行机制 1. **Read View生成** 事务首次读操作时生成包含四个要素的读视图: - `creator_trx_id`:当前事务ID - `m_ids`:活跃事务ID集合 - `min_trx_id`:最小活跃事务ID - `max_trx_id`:预分配的下个事务ID[^4] 2. **可见性判断算法** 按顺序检查每条记录的版本链: ``` if trx_id == creator_trx_id → 可见(当前事务修改) elif trx_id < min_trx_id → 可见(已提交事务) elif trx_id >= max_trx_id → 不可见(未来事务) elif trx_id in m_ids → 不可见(活跃事务) else → 可见(已提交事务) ``` #### 三、版本控制实现 1. **数据更新流程** - 插入新记录时生成新版本 - 更新操作会创建新版本并更新回滚指针 - 删除操作标记为删除状态[^5] 2. **清理机制** 通过`purge`线程定期清理不再需要的旧版本数据,清理条件: $$事务ID < 当前最旧活跃事务ID\ \&\&\ 无Read View依赖$$ #### 四、与事务隔离的对应关系 | 隔离级别 | 快照生成时机 | 可见性范围 | |----------------|----------------------|---------------------| | 读未提交 | 不使用MVCC | 直接读取最新数据 | | 读已提交(RC) | 每次查询生成新快照 | 已提交事务的最新版 | | 可重复读(RR) | 首次查询生成固定快照 | 事务开始时的数据版 | | 串行化 | 使用锁机制 | 无并发访问 | #### 五、读写操作类型 1. **快照读** ```sql SELECT * FROM table; -- 使用Read View读取可见版本[^2] ``` 2. **当前读** ```sql SELECT * FOR UPDATE; -- 直接读取最新数据并加锁[^3] ``` [^1]: 事务隔离机制与MVCC的关系说明 [^2]: 快照读与当前读的对比分析 [^3]: 版本链构建过程的技术实现 [^4]: Read View生成规则详述 [^5]: 数据清理机制实现原理
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值