*mysql mvcc 原理

本贴最后更新于 929 天前,其中的信息可能已经沧海桑田

1.概念

mvcc( muti version concurrency control), 多版本并发控制 , RC 和 RR 隔离级别是基于 mvcc 机制 ,数据库中的某条记录同时具有多个版本,在事务进行操作中时根据事务 id 以及隔离级别去判断读取哪个版本. mvcc 实现了读写并发,相较于加锁,整体效率得到提升.

2.涉及知识点

2.1 undolog & 版本链

当对一条数据进行修改时,会生成一个与修改相反的日志以便进行数据还原, 即 undo log

每次修改都会记录 undolog 节点的指针, 多个版本通过回滚指针链接在一起,形成一个链表,即版本链

image.png

undolog 主要用于:

  1. 事务回滚
  2. 快照读

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) ,其主要用来做可见性判断的

image.png

  • 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 的流程

  1. 获取当前事务版本号(事务 id),开启 readview(readview 中记录 m_ids,max_id,min_id 以及 creator_id)
  2. 查询数据以及数据的版本号(trx_id)
  3. 验证是否符合可见性原则,如果符合返回数据,如果不符合根据版本链找到上个版本继续验证

3.2 RC 模式下与 RR 模式下处理可重复读

image.png

image.png

image.png

如上图所示,初始值为孙权,版本号 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,根据可见性公式判断,数据不可见,即第二次查询数据为孙权

  • MySQL

    MySQL 是一个关系型数据库管理系统,由瑞典 MySQL AB 公司开发,目前属于 Oracle 公司。MySQL 是最流行的关系型数据库管理系统之一。

    676 引用 • 535 回帖 • 1 关注
  • MVCC
    4 引用 • 4 回帖
3 操作
AshShawn 在 2022-03-30 08:39:05 更新了该帖
AshShawn 在 2022-03-28 23:24:30 更新了该帖
AshShawn 在 2022-03-28 20:02:42 更新了该帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...