事务原子性保证的基础--undo log

2020-03-08  本文已影响0人  wbpailxt
compact行格式
数据记录和undo log记录的关系
insert操作对应的undo log记录

当我们向某个表中插入一条记录时,实际上需要向聚簇索引和所有的二级索引都插入一条记录。不过记录undo日志时,我们只需要考虑向聚簇索引插入记录时的情况就好了,因为其实聚簇索引记录和二级索引记录是一一对应的,我们在回滚插入操作时,只需要知道这条记录的主键信息,然后根据主键信息做对应的删除操作,做删除操作时就会顺带着把所有二级索引中相应的记录也删除掉。后边说到的DELETE操作和UPDATE操作对应的undo日志也都是针对聚簇索引记录而言的,我们之后就不强调了。

实际上insert undo只在事务回滚时起作用,当事务提交后,该类型的undo日志就没用了,它占用的Undo Log Segment也会被系统回收(也就是该undo日志占用的Undo页面链表要么被重用,要么被释放)。虽然真正的insert undo日志占用的存储空间被释放了,但是roll_pointer的值并不会被清除,roll_pointer属性占用7个字节,第一个比特位就标记着它指向的undo日志的类型,如果该比特位的值为1时,就代表着它指向的undo日志类型为insert undo。


事务中执行dellete语句到事务提交对对应记录的改动(也就是是怎么进行删除的)

delete mark阶段:正常记录转变成中间状态记录

delete mark阶段这个中间状态主要是为了实现一个称之为MVCC的功能

purge阶段:当该删除语句所在的事务提交之后,会有专门的线程后来真正的把记录删除掉

在删除语句所在的事务提交之前,只会经历阶段一,也就是delete mark阶段(提交之后我们就不用回滚了,所以只需考虑对删除操作的阶段一做的影响进行回滚)。

delete mark阶段之前会生成undo日志。


TRX_UNDO_DEL_MARK_REC类型的undo日志结构

delete操作对应undo log记录

在对一条记录进行delete mark操作前,需要把该记录的旧的trx_id和roll_pointer隐藏列的值都给记到对应的undo日志中来,就是我们图中显示的old trx_id和old roll_pointer属性。

数据记录执行删除操作后的版本链

根据TRX_UNDO_DEL_MARK_REC类型的undo日志进行回滚

//todo 这里画一个版本链的图:一条记录被事务10修改了,并且事务10提交了,删除事务20才得以进行,并且是怎么根据版本链进行rollback的。


更新操作

数据记录在进行update时的步骤.png

对记录进行更新操作的一个例子

版本链变化过程.jpg
上一篇 下一篇

猜你喜欢

热点阅读