MySQL:什么是undo log

undo log

redo 重做日志

在对buffer pool里的缓存页执行增删查改操作的时候,必须要写对应的redo log记录下来你做了哪些修改。

如下图所示,redo log都是先进入redo log buffer中的一个block,然后事务提交的时候就会刷入磁盘文件里去。

在这里插入图片描述
这样万一要是你提交事务了,结果事务修改的缓存页还没来得及刷入磁盘上的数据文件,此时MySQL宕机或者关闭了,那么buffer pool里被事务修改过的数据就全部都丢失了。

但是只要有redo log,重启MySQL之后完全可以把那些修改了缓存页,但是缓存页还没来得及刷入磁盘的事务所对应的redo log都加载出来,在buffer pool的缓存页里重做以便,就可以保证事务提交之后,修改的数据绝对不会丢

undo回滚日志

这种日志要应对的场景就是事务回滚的场景。

  • 比如现在我们一个事务里要执行一些增删改操作,那么必须是先把对应的数据页从磁盘加载出来放在buffer pool的缓存页里,然后在缓存页中执行增删改操作,同时记录redo log日志。

在这里插入图片描述

  • 但是问题来了,万一要是一个事务里的一通增删改操作执行到了一半,结果就回滚事务了呢?

  • 比如一个事务有4个增删改操作,结果目前为止已经执行了2个增删改SQL了,已经更新了一些buffer pool里的数据了,但是还有2个增删改SQL的逻辑还没有执行,此时事务要回滚了怎么办?
    在这里插入图片描述

  • 这个时候就很尴尬了,如果你要回滚事务的话,那么必须要把已经在buffer pool的缓存页里执行的增删改操作给回滚了。

  • 但是怎么回滚呢?毕竟无论是插入,还是更新,还是删除,该做的都已经做了

  • 所以在执行事务的时候,必须引入另外一种日志,就是undo log回滚日志。

这个回滚日志,记录的东西非常简单:

  • 比如如果在缓存页里执行了一个insert语句,那么此时undo log必须记录了插入数据的主键ID,回滚的时候就可以从缓存页里把这条数据给删除了;
  • 如果在缓存页里执行了一个delete语句,那么undo log必须记录下来被删除的数据,回滚的时候就得重新插入一条数据
  • 如果在缓存页里执行了一个update语句,那么起码要把更新之前的那个值记录下来,回滚的时候重新update一下,把之前更新的旧值更新回去。
  • 如果在缓存页里执行了一个select语句,因为没有改变buffer pool,因此不需要任何undo log。

如下图,在事务执行期间,除了写redo log日志还必须写undo log日志。通过undo log日志可以回滚事务。

在这里插入图片描述

在这里插入图片描述

INSRET语句的undo log回滚日志长什么样?

INSERT语句的undo log的类型是TRX_UNDO_INSERT_REC,这个undo log里包含了以下一些东西:

  • 这条日志的开始位置
  • 主键的各列长度和值:
    • 你插入一条数据,必然会有一个主键
    • 如果自己指定了一个主键,那么:
      • 可能这个主键就是一个列,比如id之类的,
      • 也可能是多个列组成的一个主键,比如“id+name+type”三个字段组成的一个联合主键
    • 所以这个主键的各列长度和值,意思就是你插如的这条数据的主键的每个列,它的长度是多少,具体的值是多少。
    • 如果你没有设置主键,MySQL自己会弄一个row_id作为隐藏字段做主键
  • 表id:
    • 插入一条数据必然是往一个表里面插入数据的,那当然有一个表id,记录下来是在哪个表里面插入的数据了
  • undo log日志编号:
    • 每个undo log都有自己的编号
    • 而一个事务里会有多个SQL语句,就会有多个undo log日志,在每个事务的undo log日志的编号都是从0开始的,然后依次递增
  • undo log日志类型:
    • insert语句的undo log日志类型为TRX_UNDO_INSERT_REC
  • 这条日志的结束位置

在这里插入图片描述
有了这条日志之后,剩下的事儿就好办了:

  • 万一要是你现在在buffer pool的一个缓存页里插入了一条数据了,执行了insert语句,然后你写了一条上面的那种undo log,现在事务要是回滚了,你直接就把这条insert语句的undo log拿出来。
  • 然后在undo log里就知道在哪个表里插入的数据,主键是什么,直接定位到那个表和主键对应的缓存页,从里面删除掉之前insert语句插入进去的数据就可以了,这样就可以实现事务回滚的效果了!
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL中的Redo Log、BinlogUndo Log是三种不同的日志类型,用于支持数据库事务的持久性、复制和回滚操作。 1. Redo Log(重做日志): Redo LogMySQL引擎内部使用的一种日志,记录了所有已提交的修改操作,以保证数据库在发生崩溃等异常情况下能够进行恢复。当数据库发生崩溃时,可以通过Redo Log来重放这些修改操作,使数据库恢复到崩溃前的状态。Redo Log是在InnoDB存储引擎中实现的,通常以磁盘文件形式存在,可被视为一种类似于事务日志的机制。 2. Binlog(二进制日志): BinlogMySQL数据库服务器层产生的一种日志,用于记录数据库中所有的修改操作,包括数据修改和数据定义语句(DDL)。与Redo Log不同,Binlog记录的是逻辑操作而不是物理操作,以提供对数据的逻辑复制和恢复能力。Binlog通常以二进制文件的形式存在,并且可以被用于主从复制和数据恢复等任务。 3. Undo Log(回滚日志): Undo Log是用于支持事务回滚操作的一种日志。当一个事务执行修改操作时,旧值会被记录在Undo Log中,以便于回滚操作时能够恢复到之前的状态。Undo Log通常与事务的隔离级别和并发控制有关,主要用于MVCC(多版本并发控制)的实现。 这三种日志在MySQL中扮演了不同角色,分别用于保证数据的持久性、支持复制和提供事务回滚功能。在数据库的正常运行和异常恢复中起到至关重要的作用。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值