mysql中的undo页_《mysql》之undolog

undo log有两个作用:提供回滚和MVCC。

undo log是逻辑日志。

undo log存在于一个特殊的段中,存在于表空间中,和主键id组织的数据存在一个文件中,毕竟每行数据都有个指向undo log的指针。

4)都说redo是物理日志(绝大部分是,不纠结),undo是逻辑日志,并且你新增,undo log会记录删除,你更新他会记录相反的更新,

这里有两个点,怎么理解物理日志和逻辑日志,怎么理解是记录相反操作,新增和删除相反可以理解,那更新x = x - 10相反难道是x = x

+ 10,你减去10,相反我就给你加上10,我相信肯定好大一部分人都这么理解,这么理解就坑大了。

redo确实绝大部分是物理日志,物理日志的意思就是有个日志文件存放,记录了每个物理地址目前的值到底是多少,

至于undo log,如果一个新增操作,undo log记录的是一个删除类型,甚至都不需要copy任何数据,当读到这个版本,发现了删除标记,

就可以直接返回null了

如果是个更新操作,那么copy一下更新前的值,没有更新的当然不用copy,也并不需要记录某个物理地址上是某个特定的值,当你读到这个undo log,那么就把读到的数据根据需要更新成undo log里对应的数据就行了。

如果是一个删除操作,则将这行记录copy到undo log中,然后将原始数据标记成已经删除。

这种日志难道不能看成是一种逻辑日志吗,与当前操作相反的一种逻辑日志,不需要记录对应物理地址上是些什么内容的逻辑日志。

当执行rollback时,就可以从undo log中的逻辑记录读取到相应的内容并进行回滚。

有时候应用到行版本控制的时候,也是通过undo log来实现的:当读取的某一行被其他事务锁定时

它可以从undo log中分析出该行记录以前的数据是什么,从而提供该行版本信息,让用户实现非锁定一致性读取。

undo log的存储方式

innodb存储引擎对undo的管理采用段的方式。rollback segment称为回滚段,每个回滚段中有1024个undo log segment。

在以前老版本,只支持1个rollback segment,MySQL5.5可以支持128个rollback segment,即支持128*1024个undo操作,还可以通过变量 innodb_undo_logs自定义多少个rollback segment,默认值为128。

undo log默认存放在共享表空间中。

默认rollback segment全部写在一个文件中,但可以通过设置变量 innodb_undo_tablespaces平均分配到多少个文件中。

delete/update操作的内部机制

当事务提交的时候,innodb不会立即删除undo log,因为后续还可能会用到undo log,如隔离级别为repeatable read时,事务读取的都是开启事务时的最新提交行版本,只要该事务不结束,该行版本就不能删除,即undo log不能删除。

但是在事务提交的时候,会将该事务对应的undo log放入到删除列表中,未来通过purge来删除。

并且提交事务时,还会判断undo log分配的页是否可以重用,如果可以重用,则会分配给后面来的事务,避免为每个独立的事务分配独立的undo log页而浪费存储空间和性能。

通过undo log记录delete和update操作的结果发现:

delete操作实际上不会直接删除,而是将delete对象打上delete flag,标记为删除,最终的删除操作是purge线程完成的。

update分为两种情况:update的列是否是主键列。

如果不是主键列,在undo log中直接反向记录是如何update的。即update是直接进行的。

如果是主键列,update分两部执行:先删除该行,再插入一行目标行。

insert undo log和update undo log为啥要分开,为啥提交之后insert undo log可以直接删除了,update undo log需要等待purge?

如果某个事务ID=100新增了一条记录,那么在这个事务版本之前这个记录是不存在的

这条数据要么是事务100提交的,然后就存在这条数据了

事务100没有提交,这条数据是nul

这条数据本身就是一个版本,要么是不存在,读取不到,要么就是存在,可以读取

数据是否存在,在RC和RR级别看事务有没有提交。

undo log 分成两种格式

一种给insert操作。记录中不含回滚指针,不含旧值。insert之前是没有的。

一种给update/delete操作。有回滚指针,有旧值。

对于INSERT_UNDO,调用函数trx_undo_page_report_insert进行插入,记录格式大致如下图所示:

f793447008357d79f00080fe0587e77b.png

对于UPDATE_UNDO,调用函数trx_undo_page_report_modify进行插入,UPDATE UNDO的记录格式大概如下图所示:

97e0843c49c3e75a15d3d7d552f6467e.png

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值