MySQL-ReadView在 MVCC 里如何工作?

ReadView在 MVCC 里如何工作?

Created: October 16, 2023 7:01 PM
Class: MySQL
Reviewed: No

MySQL InnoDB 引擎的默认隔离级别是可重复读,但是使用到了快照读和当前读来一定程度避免了幻读的发生。

  • 快照读:对应普通 select 语句,通过 MVCC 方式解决了幻读,在事务执行过程中,看到的数据与事务启动时看到的数据是一致的,即使途中有其他事务插入了一条数据,事务仍是查询不到这条数据的。
  • 当前读:对应 select for update 语句,通过 next-key lock 即记录锁+间隙锁解决幻读。执行 select for update 时,会为这个范围的记录数据上锁,有其他事务在锁范围插入数据会被阻塞。

Read View 是什么?

Read View 有四个重要字段:

  • m_ids:指创建 ReadView 时,当前数据库活跃事务的 ID 列表;
  • min_trx_id:指创建 ReadView 时,当前数据库活跃事务中ID 最小的事务;
  • max_trx_id:指创建 ReadView 时,当前数据库应给给下一事务的 ID 值;
  • creator_trx_id:创建该 ReadView 的事务其 ID。

「活跃事务是指已经启动但未提交的事务」

InnoDB 的聚簇索引记录中有两个隐藏列:

  • trx_id:将对聚簇索引记录改动的事务 ID 记录在 trx_id 隐藏列中;
  • roll_pointer:记录一个指针,指向 undo log 中的一条数据,这个数据是指聚簇索引被更改的旧版本数据。

两者有什么联系呢?

创建 ReadView 时,ReadView帮助我们把记录中的 trx_id 划分成三种情况,分别对应三中不同状态的事务:

Untitled

当前事务需要更改记录时会带着记录的隐藏列 trx_id 的值去 ReadView 中比较。

  • 若是小于 min_trx_id,表示当前记录的版本在创建 ReadView 之前已经提交的事务生成的,可以认为其为不活跃事务,这条记录就对于当前事务可见;
  • 若是大于 max_trx_id,表示当前记录的版本是在创建 ReadView 之后才提交的事务生成的,可以认为其为还没有开始的事务,这条记录就对于当前事务不可见;
  • 若是 min_trx_id < trx_id < max_trx_id,此时就需要判断trx_id 是否在 m_ids 中:
    • trx_id 在 m_ids 中,表示事务仍未提交,该版本记录对当前事务不可见
    • trx_id 不在 m_ids 中,表示事务已经提交,该版本记录对当前事务可见。

这种通过「版本链」来控制并发事务访问同一个记录时的行为就叫 MVCC(多版本并发控制)

之前说到过读提交以及可重复读都用到了ReadView,接下来讲一讲如何实现的。

可重复读是如何工作的

可重复读的隔离机制会在启动事务时生成一个 ReadView,整个事务期间都在使用这个 ReadView。

可重复读指:一个事务执行过程中看到的数据,一直跟这个事务启动时看到的数据是一致的。

如何做到的呢?

当前事务开始时,创建一个自己的 ReadView,当读到的记录trx_id 值属于不可见的情况时,会带着 roll_pointer 指针找到旧版本的数据,直到 trx_id 在当前事务的 ReadView 中被判断为可见为止。

Untitled

读提交是如何工作的

读提交的隔离机制是在每次读取数据时,生成一个新的 ReadView。

读提交是指:一个事务提交之后,它做的变更才能够被其他事务看到。

具体是怎么执行的呢?

当事务开始读取数据时,生成一个 ReadView,当读到记录的 trx_id 对应到 ReadView 中属于不可见的情况时,会根据版本链去找到可见版本的记录,但是当事务读取数据期间,这个记录已经被提交了,在新生成的 ReadView 中,这个记录不处于 m_ids 列表之中,就会导致其读到的值是最新的,所以读提交会有不可重复读的现象——即同一事务下读同一个记录的值不相同。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值