innodb MVCC

32 篇文章 0 订阅

undo log

回滚段是记录MVCC历史的一个空间,如果开启了独立表空间,会在独立表空间中创建一个回滚表空间,undo表空间有128个段,其中:
1~32段存放于临时表的系统表空间中
33~127段存放于独立undo表空间中
为了事物并发,每个undo段又分为1024个slot
理论上来说,innodb可支持96*1024个事物并发

RR和RC

RR隔离级别(除了Gap锁之外)和RC隔离级别的差别是创建snapshot时机不同。 RR隔离级别是在事务开始时刻,确切地说是第一个读操作创建read view的;RC隔离级别是在语句开始时刻创建read view的。
read view:将当前活跃的事物做一个视图。当在这个事务中要读取该行记录的时候,innodb会将该行当前的版本号与该read view进行比较。

innodb表空间

innodb表空间结构
在理解MVCC如何使用回滚段之前,先了解一下undo段所在的位置。
段–>区–>页–>行
任何情况下,区的大小为1M,在页(16K)装满时,innodb会一次申请4个区

MVCC的undo原理

1、分配回滚段

每当只读事物开始时,会为其分配一个回滚段,如果对临时表产生了写入操作,则会分配到临时表回滚段。如果是普通的只读事物,那么会:
1)采用round-robin的轮询方式来赋予回滚段给事务,如果回滚表空间过大,无法为其分配的时候,purge线程会执行truncate操作。
2)清除操作完成后,选择一个回滚段给事务后,内部会记录一个记录值,表示该事物比上一次清除的值大,是新事物,这样就不会被truncate掉。
3)如果事务在只读阶段使用到临时表,随后转换成读写事务,那么会为该事务分配两个回滚段。

2、使用回滚段

当数据产生变更时,undo日志会记录下变更前的数据以记录历史版本。其中:
	insert记录一个undo,delete、update记录一个undo,因此两种操作需要单独分配slot。
具体使用流程:
1)判断当前事物是否使用临时表,如果使用临时表,则为其分配临时表回滚段
2)在临时表操作时不会记录其redo log
3)操作类型为INSERT时,且未分配slot时,为其分配undo slot
4)操作类型为update/delete,且未分配slot时,为其分配undo slot

3、事物Prepare阶段

当事务完成需要提交时,为了和BINLOG做XA,InnoDB的commit被划分成了两个阶段:prepare阶段和commit阶段
为了防止崩溃重启时知道事物的状态,所以设置事物为Prepare
innodb事物在执行sql时,会注册一个XID号,然后存储在事务对象中

4、事务Commit

当事物完成需要提交时,设置事物状态为Commit,先设置insert undo,再设置update

5、事务回滚

如果事物因各种原因需要回滚时,这里就需要借助undo log中的数据来进行恢复
先解析老版本记录,做逆向操作:对于标记删除的记录清理标记删除标记;对于in-place更新,将数据回滚到最老版本;对于插入操作,直接删除聚集索引和二级索引记录。

MVCC

innodb的MVCC是通过每行记录后面三个隐藏列实现。一列记录了事物ID,一列记录了回滚指针,一列记录了行ID。
1)INSERT:插入操作,每次插入时都新生成一个系统版本号,在原来基础上递增
2)DELETE:删除操作,每次删除时都会记录当前版本号,标记为删除版本号
3)UPDATE:实际上包含了两次操作,一次为INSERT操作,插入一行新的记录,生成新的版本号,记录旧ID标记为删除版本号
当在这个事务中要读取该行记录的时候,innodb会将该行当前的版本号与该行记录的read view进行比较。
select语句可见的情况:
版本号<= 当前事务版本号 (记录是在当前事务之前或者由当前事务创建的)
删除版本号 == NULL || 删除版本号 > 当前事务版本号 (记录是在当前事务之后被删除的)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值