1.概念
mvcc( muti version concurrency control), 多版本并发控制 , RC 和 RR 隔离级别是基于 mvcc 机制 ,数据库中的某条记录同时具有多个版本,在事务进行操作中时根据事务 id 以及隔离级别去判断读取哪个版本. mvcc 实现了读写并发,相较于加锁,整体效率得到提升.
2.涉及知识点
2.1 undolog & 版本链
当对一条数据进行修改时,会生成一个与修改相反的日志以便进行数据还原, 即 undo log
每次修改都会记录 undolog 节点的指针, 多个版本通过回滚指针链接在一起,形成一个链表,即版本链
undolog 主要用于:
- 事务回滚
- 快照读
2.2 隐式字段
每条数据都有 3 个隐式字段
row_id: 当数据记录无主键时会使用 row_id 代替主键
trx_id: 最新事务 id
roll_pointer: 回滚指针,指向 undolog
2.3 快照读&当前读
快照读: 读取数据的可见版本, 不加锁
当前读: 读取数据的当前版本(最新), 加锁
select * from t lock in share mode; //共享读锁
select * from t for update; //写锁
2.4 read view
事务中执行 sql 语句则会开启一个 read view (RC 级别下,每个 sql 开启一个 readview, RR 级别下,每个事务开启一个 readview) ,其主要用来做可见性判断的
- m_ids:当前系统中那些活跃(未提交)的读写事务 ID, 它数据结构为一个 List。
- min_limit_id:表示在生成 Read View 时,当前系统中活跃的读写事务中最小的事务 id,即 m_ids 中的最小值。
- max_limit_id:表示生成 Read View 时,系统中应该分配给下一个事务的 id 值。
- creator_trx_id: 创建当前 Read View 的事务 ID
//可见性判断,trx_id为版本链中某个版本的事务id
if(trx_id < min_limit_id) return true;
if(trx_id >= max_limit_id) return false;
if(min_limit_id =<trx_id< max_limit_id){
if(!m_ids.contains(trx_id)) return true;
else if(m_ids.contains(trx_id) && trx_id==creator_trx_id) return true;
return false;
}
3. mvcc 原理
3.1 查询 sql 的流程
- 获取当前事务版本号(事务 id),开启 readview(readview 中记录 m_ids,max_id,min_id 以及 creator_id)
- 查询数据以及数据的版本号(trx_id)
- 验证是否符合可见性原则,如果符合返回数据,如果不符合根据版本链找到上个版本继续验证
3.2 RC 模式下与 RR 模式下处理可重复读
如上图所示,初始值为孙权,版本号 100, 后事务 B 更新为曹操,版本号为 101
在 RC 级别下
第一个 select 时,开启 readview,参数如下:
变量 | 值 |
---|---|
m_ids | 100,101 |
max_limit_id | 102 |
min_limit_id | 100 |
creator_trx_id | 100 |
最新数据版本为 100, 根据可见性公式判断,数据可见,即第一次查询数据为孙权
第二个 select 时,开启 readview,参数如下
变量 | 值 |
---|---|
m_ids | 100 |
max_limit_id | 102 |
min_limit_id | 100 |
creator_trx_id | 100 |
最新数据版本为 101,根据可见性公式判断,数据也可见,即第二次查询数据为曹操
此时, 不可重复读问题产生了
在 RR 级别下
第一个 select 时,开启 readview,参数如下:
变量 | 值 |
---|---|
m_ids | 100,101 |
max_limit_id | 102 |
min_limit_id | 100 |
creator_trx_id | 100 |
最新数据版本为 100, 根据可见性公式判断,数据可见,即第一次查询数据为孙权
第二个 select 时,由于是 RR 级别,沿用之前的 readview,参数如下
变量 | 值 |
---|---|
m_ids | 100,101 |
max_limit_id | 102 |
min_limit_id | 100 |
creator_trx_id | 100 |
最新数据版本为 101,根据可见性公式判断,数据不可见,即第二次查询数据为孙权
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于