undo log 事务回滚操作

undo log 回滚操作

undo是什么

undo日志用于存放数据修改被修改前的值,假设修改 tba 表中 id=2的行数据,把Name=‘B1’ 修改为Name = ‘B2’ ,那么undo日志就会用来存放Name='B1’的记录,如果这个修改出现异常,可以使用undo日志来实现回滚操作,保证事务的一致性。

  • undo是逻辑日志,只是将数据结构和页本身逻辑的恢复到原来的样子
  • 对数据库进行修改的时候,InnoDB存储引擎不但会产生redo,还会产生一定量的undo,这样如果用户执行的事务或语句由于某种原因失败了,又或者用户一条ROLLBACK语句请求失败了,就可以利用这些undo信息将数据回滚到修改之前的样子

为什么不是物理日志

在多用户并发系统中,可能有数十数千个修改当前页中的某几条数据,同时还有别的事务在对同一个页中另几条记录进行修改,因此不能将一个页混滚到事务开始的样子,采用了逻辑恢复的样子
是insert的时候就delete 是update的时候就采用相对的update来恢复数据

undo 参数

show variables like "%undo%"; 

在这里插入图片描述

  • innodb_undo_log_truncate
    InnoDB的purge线程,根据innodb_undo_log_truncate设置开启或关闭、innodb_max_undo_log_size的参数值,以及truncate的频率来进行空间回收和 undo file 的重新初始化。
    该参数生效的前提是,已设置独立表空间且独立表空间个数大于等于2个

  • innodb_max_undo_log_size
    控制最大undo tablespace文件的大小,当启动了 innodb_undo_log_truncate 时,undo tablespace 超过 innodb_max_undo_log_size 阀值时才会去尝试truncate。该值默认大小为 1G,truncate后的大小默认为10M。

  • innodb_undo_tablespaces
    设置undo独立表空间个数,范围为0-128, 默认为0,0表示表示不开启独立undo表空间 且 undo日志存储在ibdata文件中。该参数只能在最开始初始化MySQL实例的时候指定,如果实例已创建,这个参数是不能变动的,如果在数据库配置文 件 .cnf 中指定innodb_undo_tablespaces 的个数大于实例创建时的指定个数,则会启动失败,提示该参数设置有误。

  • innodb_undo_directory
    设置rollback segment文件所在位置的路径,这意味着rollback segment可以存放在共享表空间以外的位置,即可以设置为独立表空间,该参数的默认值为”.”,标识当前InnoDB存储引擎的位置的目录

  • innodb_undo_log
    用来设置rollback segment的个数,默认值为128个

undo空间管理

如果需要设置独立表空间,需要在初始化数据库实例的时候,指定独立表空间的数量。
UNDO内部由多个回滚段组成,即 Rollback segment,一共有128个,保存在ibdata系统表空间中,分别从resg slot0 - resg slot127,每一个resg slot,也就是每一个回滚段,内部由1024个undo segment 组成。
回滚段(rollback segment)分配如下:

  • slot 0 ,预留给系统表空间;
  • slot 1- 32,预留给临时表空间,每次数据库重启的时候,都会重建临时表空间;
  • slot33-127,如果有独立表空间,则预留给UNDO独立表空间;如果没有,则预留给系统表空间;
    回滚段中除去32个提供给临时表事务使用,剩下的 128-32=96个回滚段,可执行 96*1024 个并发事务操作,每个事务占用一个 undo segment slot,注意,如果事务中有临时表事务,还会在临时表空间中的 undo segment slot 再占用一个 undo segment slot,即占用2个undo segment slot。如果错误日志中有:Cannot find a free slot for an undo log。则说明并发的事务太多了,需要考虑下是否要分流业务。
    回滚段(rollback segment )采用 轮询调度的方式来分配使用,如果设置了独立表空间,那么就不会使用系统表空间回滚段中undo segment,而是使用独立表空间的,同时,如果回滚段正在 Truncate操作,则不分配。

undo log 在事务中的流程

事务在undo log segment分配也写入undo log的同时也会产生redo log,当事务提交时候(commit)
1.将undo log 放入列表中,以供之后的purge(pai rui chi)线程使用
2.判断undo log 所在的页是否可以重用,若可以分配给下个事务使用
3.事务提交后,不能马上删除undo log及undo log所在的页,这是因为还有其他事务需要通过undo log来得到行记录之前的版本,故事务提交将undo log 放入一个链表中,是否可以最终删除undo log及undo log所在页由purge线程来判断

当事务提交时候,首先将undo log放入链表中,判断undo页的使用空间是否小于3/4,则表示undo log可以被重用,之后新的undo log 记录在当前的undo log的后面,由于存放undo log的列表是以记录进行组织的,二undo log可能存放着不同事务的undo log,因此prege操作需要设计磁盘的离散读取操作,是一个比较缓慢的过程,此过程可以设置purge线程的个数来提升回收速度

undo log 种类

1.insert undo log是值在insert操作中产生的undo log,因为insert操作记录,只对本身事务可见,对其他事物不可见,顾此undo log可以在事务提交后直接删除.
2.insert undo log记录的是直接修改后的操作,录入a +=1,记录的是a=2
3.update undo log记录的是对delete和update操作产生的undo log,该undo log可能需要提供MVCC机制,故不能再事务提交后就删除,提交时候记录到undo log链表,等待purge线程进行最后的删除
4.delete的是将删除的标记为已删除 delete flag为1,而最终的删除是在pruge操作中完成
update undo log是删除主键的记录,标记为已删除,产生一条新的逆向过程的记录

查看undo数量

show innodb_engine_status中的TRANSACTIONS history list length
purge thread
负责回收已经使用并分配的undo页,purge操作默认是由master thread中完成的,为了减轻master thread的工作,提高cpu使用率以及提升存储引擎的性能。用户可以在参数文件中添加如下命令来启动独立的purge thread。
innodb_purge_threads=1
从innodb1.2版本开始,可以指定多个innodb_purge_threads来进一步加快和提高undo回收速度。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

a...Z

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

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

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

打赏作者

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

抵扣说明:

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

余额充值