mysql数据库 | undo & redo 日志
发布日期:2022-02-21 17:40:22 浏览次数:36 分类:技术文章

本文共 2447 字,大约阅读时间需要 8 分钟。

mysql数据库 | undo & redo 日志

1. Undo Log

undo日志用于存放数据修改被修改前的值

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

undo 默认内存 : 1G , truncate后的大小默认为10M

1.1 Undo Log的空间管理

UNDO内部由多个回滚段组成,即 Rollback segment,一共有128个,保存在ibdata系统表空间中,分别从resg slot0 ----> resg slot127,每一个resg slot,也就是每一个回滚段,内部由1024个undo segment 组成。

回滚段(rollback segment)分配如下:

  • slot 0 ,预留给系统表空间;
  • slot 1- 32,预留给临时表空间,每次数据库重启的时候,都会重建临时表空间;
  • slot33-127,如果有独立表空间,则预留给UNDO独立表空间;如果没有,则预留给系统表空间;

2. Redo Log

当数据库对数据做修改的时候,需要把数据页从磁盘读到buffer pool中,然后在buffer pool中进行修改,那么这个时候buffer pool中的数据页就与磁盘上的数据页内容不一致,称buffer pool的数据页为dirty page 脏数据,如果这个时候发生非正常的DB服务重启,那么这些数据还没在内存,并没有同步到磁盘文件中(注意,同步到磁盘文件是个随机IO),也就是会发生数据丢失,如果这个时候,能够在有一个文件,当buffer pool 中的data page变更结束后,把相应修改记录记录到这个文件(注意,记录日志是顺序IO),那么当DB服务发生crash的情况,恢复DB的时候,也可以根据这个文件的记录内容,重新应用到磁盘文件,数据保持一致。

这个文件就是 Redo Log ,用于记录 数据修改后的记录,顺序记录。

它可以带来这些好处:

  • 当buffer pool 中的 dirty page 还没有刷新到磁盘的时候,发生crash,启动服务后,可通过redo log 找到需要重新刷新到磁盘文件的记录;
  • buffer pool 中的数据直接 flush 到 disk file,是一个随机IO,效率较差,而把buffer pool中的数据记录到redo log,是一个顺序IO,可以提高事务提交的速度;

假设修改 tba 表中 id=2的行数据,把Name=’B’ 修改为Name = ‘B2’ ,那么redo日志就会用来存放Name=’B2’的记录,如果这个修改在flush 到磁盘文件时出现异常,可以使用redo log实现重做操作,保证事务的持久性。

3. Undo + Redo事务的简化过程

假设有A、B两个数据,值分别为1,2,开始一个事务

事务的操作内容为:把1修改为3,2修改为4,那么实际的记录如下(简化):

A.事务开始.

B.记录A=1到undo log.
C.修改A=3.
D.记录A=3到redo log.
E.记录B=2到undo log.
F.修改B=4.
G.记录B=4到redo log.
H.将redo log写入磁盘。
I.事务提交

4. 事务恢复

未提交的事务和回滚了的事务也会记录在Redo Log中,因此在进行恢复时,这些事务要进行特殊的的处理。有2种不同的恢复策略:

  1. 进行恢复时,只重做已经提交了的事务。
  2. 进行恢复时,重做所有事务包括未提交的事务和回滚了的事务。然后通过Undo Log回滚那些
    未提交的事务。

MySQL数据库InnoDB存储引擎使用了B策略, InnoDB存储引擎中的恢复机制有几个特点:

  1. 在重做Redo Log时,并不关心事务性。 恢复时,没有BEGIN,也没有COMMIT,ROLLBACK的行为。也不关心每个日志是哪个事务的。尽管事务ID等事务相关的内容会记入Redo Log,这些内容只是被当作要操作的数据的一部分。
  2. 使用2策略就必须要将Undo Log持久化,而且必须要在写Redo Log之前将对应的Undo Log写入磁盘。Undo和Redo Log的这种关联,使得持久化变得复杂起来。为了降低复杂度,InnoDB将Undo Log看作数据,因此记录Undo Log的操作也会记录到redo log中。这样undo log就可以象数据一样缓存起来,而不用在redo log之前写入磁盘了。
    包含Undo Log操作的Redo Log,看起来是这样的:
记录1: 
> 记录2:
记录3:
> 记录4:
记录5:
> 记录6:

到这里,还有一个问题没有弄清楚。既然Redo没有事务性,那岂不是会重新执行被回滚了的事务?

确实是这样。同时Innodb也会将事务回滚时的操作也记录到redo log中。回滚操作本质上也是
对数据进行修改,因此回滚时对数据的操作也会记录到Redo Log中。
一个回滚了的事务的Redo Log,看起来是这样的:

记录1: 
> 记录2:
记录3:
> 记录4:
记录5:
> 记录6:
记录7:
记录8:
记录9:

一个被回滚了的事务在恢复时的操作就是先redo再undo,因此不会破坏数据的一致性。

转载地址:https://blog.csdn.net/weixin_40597409/article/details/115433415 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Java中的锁 | 锁的种类
下一篇:Java中的锁 | Sychronized 原理

发表评论

最新留言

路过按个爪印,很不错,赞一个!
[***.219.124.196]2024年04月15日 16时30分38秒