栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Mysql的MVCC原理

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Mysql的MVCC原理

我们知道,在Mysql的RC隔离级别下和RR隔离级别下MVCC才会生效,它的实现原理是靠undo log版本连以及Read View来实现的,下面我们来分析一下。

快照读

快照读很简单,其实就是普通的select,是一种非阻塞无锁操作。

当前读

读的是当前最新的数据,比如 select ···· for update,insert,update等都是当前读,是要加锁的。

隐藏字段

在每一行记录的后面其实会有两个隐藏字段
DB_TRX_ID:保存在该行记录上执行insert语句或者update语句的当前事务ID。
DB_ROLL_PTR:回滚指针,记录着该记录的上一个版本,相当于链表的next指针。

Read View

Read View是进行快照读的依据,是一种数据结构,它由四个部分组成

  1. m_ids:当前活跃的所有事务ID
  2. min_trx_id:最小活跃事务ID
  3. max_trx_id:下一个事务ID,最大活跃事务ID + 1
  4. creator_trx_id:创建该Read View的事务ID

对每一个事务,只能读到小于等于DB_TRX_ID(行记录的隐藏字段)的版本的数据,比如说现在的事务ID是4,它只能读到1到4版本的数据,那么该读哪个版本呢?要遵循以下逻辑:
(注意:以下的当前事务ID是指版本链中记录的每一个已操作的事务ID)

  1. 判断当前事务ID是否等于creator_trx_id,如果相等,表示是自己修改了自己,当然可以访问,如果不相等,进入下一轮判断。
  2. 判断当前事务ID是否小于min_trx_id,如果小于,表示事务已经提交,当然可以访问,如果不相等,进入下一轮判断。
  3. 判断当前事务ID是否大于max_trx_id,如果大于,则表示该事务实在ReadView生成以后再开启的,不允许访问,如果小于,则进入下一轮判断。
  4. 判断当前事务ID是否 min_trx_id <= DB_TRX_ID <= max_trx_id ,如果成立,则看看该事务ID是否在m_ids中,如果不存在,则表明事务已提交,可以读取。

而RC隔离级别和RR隔离级别的区别就在于产生Read View的时机。

RC隔离级别下的情况

在RC隔离级别下,在每次进行快照读的时候,都会生成Read View,因此每次快照读都能知道是哪些数据没有提交,再经过上述判断后,每次快照读都会读到已提交的数据,因此才会出现不可重复读的现象。

如图
InnoDB是以每一个版本链的DB_TRX_ID去比较的,一个不行就下一个直到拿到数据为止,整个过程是这样的:先从DB_TRX_ID = 2开始,发现2不等于creator_trx_id,因此下一轮循环,然后再发现2不小于min_trx_id,进入下一轮循环,发现2小于max_trx_id,进入下一轮循环,发现2是在m_ids里的,不符合,因此根据回滚指针,指向下一个版本即DB_TRX_ID = 1,再次经过上述逻辑,发现符合,因此取出DB_TRX_ID = 1的这条数据,因此第一次快照读读的是name = B,而同理,第二次快照读读的是name = C。

RR隔离级别下的情况

RR隔离级别下的情况和RC隔离级别几乎完全相同,唯一不一样的地方就是,RR级别只会生成一次Read View,之后的每次快照读都会根据这个Read View 来读,但是要注意一点,如果有当前读发生,则会清除Read View并且重新生成一个新的Read View,因此MVVC只是可以解决部分的幻读现象。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/571813.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号