MVCC的原理
第一点:对隐藏数据的认识:
**DB_TRX_ID:**我们可以认为DB_TRX_ID是最近修改的事务ID,通俗易懂的解释就是一个事务中可能有多个修改的操作,每一次修改操作进行了就会有不同的DB_TRX_ID,包括insert,update,delete,SELECT … FOR UPDATE等
**DB_ROLL_PTR:**可以将其看作一个指针,指针从最新的数据开始,指向修改了的老数据,通过指针就可以得到undolog!
DB_ROLL_PTR为null表示它是最原始的数据
**DB_ROW_ID:**对讲解没有帮助,但提一嘴,如果数据表没有主键,InnoDB会以此值作为聚簇索引
第二点:对undolog的认识
依然是这个图,再次强调undolog就是事务中只要发生了修改操作,那么就会被记录到undolog中,当然,这些事务可以使并发的,所以undolog会有很多不同DB_TRX_ID值
第三点:对ReadView的认识
- **creator_trx_id:**指的是当前的事务
- **min_trx_id:**指的是已启动但未提交的事务
- **max_trx_id:**指的是还没有开始的事务
第四点:实际分析(读已提交的MVCC处理)
**首先需要认识规则:**如果现在看不懂没关系,可以对照下面的分析一并看
**实例:**两个事务的情况
当事务10进行的时候,把balance设置成了800,按照读已提交的逻辑,事务20拿到的balance一定是事务10修改前的1000,下面是具体流程
具体流程:
- **首先分析变动的情况:**最原始的数据是500,可以看到指针那一块是空的,当事务10为修改时的数据是1000,它可能被事务10之前的数据修改过,事务10修改后的数据为800,可以看见,这些修改形成undolog版本链,接下来我将以上面给出的规则分析事物20是如何找到1000的数据的。
- **第一次查找:**事务20与第一条记录10对比,20明显不等于20,不是自己的记录,因为仅仅select不会改变DB_TRX_ID值,所有有这个检查,不符合
- **第二次查找:**min_trx_id中最小的是10,当前的DB_TRX_ID并不小于10,说明最新的数据并不是事务10修改之前的数据,不符合
- **第三次查找:**max_trx_id为21,大于DB_TRX_ID的值,这里以反例说明,只有DB_TRX_ID更大这个查找才会继续进行,进行下去是查询更老的数据,但这里是更小,那也不符合
- **第四次查找:**10在10和21之间,说明创建ReadView的时候10这个版本还未提交,那么需要找更老的数据
- **第五次查找:**同第一次查找,不符合
- **第六次查找:**同第二次查找,符合。
第五点:可重复读实现的区别
读已提交(RC) | 每次执行SELECT语句时 生成新的Read View,反映当前所有已提交事务的最新状态。 |
---|---|
可重复读(RR) | 仅在第一次SELECT时 生成Read View,后续所有SELECT沿用同一个视图,保证读取一致性。 |
感兴趣可以自行逐步分析,流程和第四点一致