MySQL中RR级别下的MVCC

众所周知MySQL中InnoDB的可重复读是通过MVCC实现的。

MVCC是由哪些元素构成?

MVCC的读 又叫快照读,在MySQL中不可能把整个表的数据拷贝一份来提供这个快照。它通过

      1、undolog

           InnoDB增删数据时除了redo log外还会记录undo log。

           以update举例: undolog->修改内存中数据页->redolog prepare->binlog-> commit; 修改数据时 undo log记录原始数据。用于以后或许会发生的回滚操作。

      2、表中的的隐藏列 data_trx_id,data_roll_pt

            一张表中有三个隐藏列

            rows_id: MySQL给予行的一个标识。如果表中没有主键,那么就会使用row_id来组织数据。

            data_trx_id: 事务id,创建一个新的事务,会分配一个自增的全局唯一的data_trx_id。

            需要说明的是:begin/start transaction 命令并不是一个事务的起点,在执行到它们之后的第一个操作 InnoDB 表的语句,事务才真正启动。

            data_roll_pt: 回滚指针,这个指针指向undo log中的一行记录原始记录。

      3、Read View数组

            创建事务时,InnoDB为事务创建了一个Read View的数组用来记录创建事务时刻的当前活跃事务data_trx_id。

            

            低水位:创建当前事务时刻活跃事务中最小的data_trx_id。很多人认为是已提交事务的最大data_trx_id,这样理解之后存在一个问题。

            比如 现在已提交事务有 1 3 ,2为活跃事务。按已提交事务的最大id来理解,低水位应该为3。与MySQL判断 小于低水位为已提交事务,就出现了矛盾。 

            高水位:创建当前事务时刻未分配的最小data_trx_id。

以上三部分来实现。

MVCC怎么工作的?

             当读取到一行数据

                     0、是否是当前事务修改,是当前事务修改,当前事务可见。

                     1、这行数据data_trx_id与低水位比较,小于低水位,则事务已提交,当前事务可见。否则判断是否大于高水位。

                     2、这行数据data_trx_id与高水位比较,大于高水位,则是在当前事务创建之后的事务,当前事务不可见。

                     3、这行数据data_trx_id与高水位比较,小于高水位,则判断Read View中是否包含此data_trx_id。如果包含则表示

当前事务创建时,data_trx_id为活跃事务,当前事务不可见。

                      4、Read View中不含此data_trx_id则表示当前事务创建时,data_trx_id为已提交事务,当前事务可见。

             举个栗子:现在已提交事务有 1 3 ,2为活跃事务,当前事务data_trx_id为4。低水位为2,高水位5。

             此时Read View中为 2 4。当读到data_trx_id为3的行时,

             1、3<2?

             2、3>5?

             3、Read View包含3?

             最后得出3对4可见。

跟undolog有什么关系?

      沿用上面的例子, 新起一个事务update对原来为data_trx_id为3的已提交事务进行操作。记录undolog,将data_trx_id由3改为5,并且data_roll_pt指向undolog中为data_trx_id为3的记录。

      当data_trx_id为4的事务,读取到data_trx_id为5的行时,data_trx_id不满足条件则通过data_roll_pt查找undolog中是否有满足条件的行,可以查找到data_trx_id为3的行。

  • 2
    点赞
  • 2
    评论
  • 0
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

©️2022 CSDN 皮肤主题:游动-白 设计师:我叫白小胖 返回首页

打赏作者

喵脚三

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值