当前位置: 首页 > article >正文

Mysql-事务日志undo log

undo log 的作用 

事务需要保证 原子性,也就是事务中的操作要么全部完成,要么什么也不做。但有时候事务执行到一半会出现一些情况,比如:

  • 情况一:事务执行过程中可能遇到各种错误,比如服务器本身的错误操作系统错误 ,甚至是突然 断电 导致的错误。

  • 情况二:程序员可以在事务执行过程中手动输入 ROLLBACK 语句结束当前事务的执行。

以上情况出现,我们需要把数据改回原先的样子,这个过程称之为 回滚 ,这样就可以造成一个假象:这个事务看起来什么都没做,所以符合 原子性 要求。

总而言之,undo log记录的就是操作的逆操作,插入一条记录,undo 记录的就是delete操作

Undo日志的作用

作用1:回滚数据

undo是逻辑日志,只是将数据库逻辑恢复到原来的样子,但对具体的数据结构和页是不会坐修改的,因为其它事务也可能会在相同的页进行数据操作,如果在数据结构和页层面进行回滚,会影响到其它事务正在进行的操作。

  • 作用2:MVCC

 undo的另一个作用是MVCC,即在InnoDB存储引擎中MVCC的实现是通过undo来完成。当用户读取一行记录时,若该记录以及被其他事务占用,当前事务可以通过undo读取之前的行版本信息,以此实现非锁定读取。  

 undo的存储结构

回滚段与undo页

InnoDB对undo log的管理采用段的方式,也就是 回滚段(rollback segment) 。每个回滚段记录了 1024undo log segment ,而在每个undo log segment段中进行 undo页 的申请。

  • InnoDB1.1版本之前 (不包括1.1版本),只有一个rollback segment,因此支持同时在线的事务限制为 1024 。虽然对绝大多数的应用来说都已经够用。

  • 从1.1版本开始InnoDB支持最大 128个rollback segment ,故其支持同时在线的事务限制提高到 了 128*1024

mysql> show variables like 'innodb_undo_logs';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| innodb_undo_logs | 128   |
+------------------+-------+

 

 undo的页是可以重用,并不会为每一个事务都单独分配一个页,当事务提交时,并不会立刻删除undo 页,因为这个页可能夹杂着其它事务的undo log ,undo log 在事务commit之后,会被放到一个链表中,然后判断该页的使用空间,如果小于4分之3的话,就不会被回收,其它事务的undo log 可以记录到当前undo 页的后面

 回滚段与事务

  1. 每个事务只会使用一个回滚段,一个回滚段在同一时刻可能会服务于多个事务

  2. 当一个事务开始的时候,会制定一个回滚段,在事务进行的过程中,当数据被修改时,原始的数据会被复制到回滚段

  3. 在回滚段中,事务会不断填充盘区,直到事务结束或所有的空间被用完。如果当前的盘区不够 用,事务会在段中请求扩展下一个盘区,如果所有已分配的盘区都被用完,事务会覆盖最初的盘 区或者在回滚段允许的情况下扩展新的盘区来使用。

  4. 回滚段存在于undo表空间中,在数据库中可以存在多个undo表空间,但同一时刻只能使用一个 undo表空间。

  5. 当事务提交时,InnoDB存储引擎会做以下两件事情:

    • 将undo log放入列表中,以供之后的purge操作

    • 判断undo log所在的页是否可以重用,若可以分配给下个事务使用

回滚段中的数据分类

事务提交后不能马上删除undo log及undo log所在的页。这是因为可能还有其他事务需要通过undo log来得到行记录之前的版本。故事务提交时将undo log放入一个链表中(MVCC版本链),是否可以最终删除undo log以undo log所在页由purge线程来判断。

  1. 未提交的回滚数据(uncommitted undo information):该数据所关联的事务并未提交,用于实现读一致性,所以该数据不能被其他事务的数据覆盖。

  2. 已经提交但未过期的回滚数据(committed undo information):该数据关联的事务已经提交,但是仍受到undo retention参数的保持时间的影响。

  3. 事务已经提交并过期的数据(expired undo information):事务已经提交,而且数据保存时间已经超过 undo retention参数指定的时间,属于已经过期的数据。当回滚段满了之后,就优先覆盖“事务已经提交并过期的数据"。

undo的类型

在InnoDB存储引擎中,undo log分为:

  • insert undo log

    insert undo log是指insert操作中产生的undo log。因为insert操作的记录,只对事务本身可见,对其他事务不可见(这是事务隔离性的要求),故该undo log可以在事务提交后直接删除。不需要进行purge操作。

  • update undo log

    update undo log记录的是对delete和update操作产生的undo log。该undo log可能需要提供MVCC机制,因此不能在事务提交时就进行删除。提交时放入undo log链表,等待purge线程进行最后的删除。

undo log的生命周期

简要生成过程

以下是undo+redo事务的简化过程

假设有两个数值,分别为A=1和B=2,然后将A修改为3,B修改为4

只有Buffer Pool的流程:

修改数据和查询数据,都是不存在就从磁盘中加载进buffer pool,更新数据时就先更新buffer pool中的数据,然后定时刷入磁盘中
 

有了Redo Log和Undo Log之后:

在更新Buffer Pool中的数据之前,我们需要先将该数据事务开始之前的状态写入Undo Log中。假设更新到一半出错了,我们就可以通过Undo Log来回滚到事务开始前。并将修改的数据同步到redo log 中


 

详细生成过程


当我们执行INSERT时:

​​​​​​​begin;
INSERT INTO user (name) VALUES ("tom"); 

 

 插入的数据都会生成一条insert undo log,并且数据的回滚指针会指向它。undo log会记录undo log的序号、插入主键的列和值...,那么在进行rollback的时候,通过主键直接把对应的数据删除即可。

当我们执行UPDATE时:  

对应更新的操作会产生update undo log,并且会分更新主键和不更新主键的,假设现在执行:

UPDATE user SET name="Sun" WHERE id=1;

这时会把老的记录写入新的undo log,让回滚指针指向新的undo log,它的undo no是1,并且新的undo log会指向老的undo log(undo no=0)。  

 UPDATE user SET id=2 WHERE id=1;

 

对于更新主键的操作,会先把原来的数据deletemark标识打开,这时并没有真正的删除数据,真正的删除会交给清理线程去判断,然后在后面插入一条新的数据,新的数据也会产生undo log,并且undo log的序号会递增。

可以发现每次对数据的变更都会产生一个undo log,当一条记录被变更多次时,那么就会产生多条undo log,undo log记录的是变更前的日志,并且每个undo log的序号是递增的,那么当要回滚的时候,按照序号依次向前推,就可以找到我们的原始数据了

undo log是如何回滚的


以上面的例子来说,假设执行rollback,那么对应的流程应该是这样:

  1. 通过undo no=3的日志把id=2的数据删除

  2. 通过undo no=2的日志把id=1的数据的deletemark还原成0

  3. 通过undo no=1的日志把id=1的数据的name还原成Tom

  4. 通过undo no=0的日志把id=1的数据删除

undo log的删除

  • 针对于insert undo log

    因为insert操作的记录,只对事务本身可见,对其他事务不可见。故该undo log可以在事务提交后直接删除,不需要进行purge操作。

  • 针对于update undo log

    该undo log可能需要提供MVCC机制,因此不能在事务提交时就进行删除。提交时放入undo log链表,等待purge线程进行最后的删除。

小结 

undo log是逻辑日志,对事务回滚时,只是将数据库逻辑地恢复到原来的样子。

redo log是物理日志,记录的是数据页的物理变化,undo log不是redo log的逆过程。

 

 


http://www.kler.cn/a/551593.html

相关文章:

  • React实现自动滚动表格
  • 【Python】实时将数据写入Excel
  • 分布式同步锁:原理、实现与应用
  • 国产编辑器EverEdit - 自动完成功能的用法
  • 蓝桥杯单片机基础部分——单片机介绍部分
  • 安装torch-geometric库,踩坑!
  • Ubuntu Linux运维实战指南4_文件系统基础知识
  • git自动化之.netrc配置
  • 【云安全】云原生- K8S 污点横移
  • 算法与数据结构(子集)
  • 深入解析 iOS 视频录制(三):完整录制流程的实现与整合
  • 基于SpringBoot的个人学习记录平台的设计
  • flash attention
  • k8s集群如何赋权普通用户仅管理指定命名空间资源
  • 【Cesium学习(十)】Cesium 中对 3D 瓦片集进行样式化(Cesium3DTileStyle)
  • 使用vue2 脚手架 结合 Element UI 写一个电商商城前端静态网站模板-前端项目练习
  • 【生产变更】- 集群中配置SCAN ip的不同端口应用
  • 单点登录(SSO)与单例登录(Single Login)学习笔记
  • 北京海百川科技有限公司:以智能体技术助力特殊教育行业
  • 当机器人遇见艺术:春晚机器人舞蹈,一场科技与艺术的完美邂逅