redo日志和undo日志

本文详细介绍了MySQL数据库中的redo日志(重做日志)和undo日志的作用、特性及工作流程。redo日志用于崩溃恢复,通过Write-Ahead Log策略确保事务持久性,而undo日志用于事务的回滚操作,保证原子性。文章还讨论了脏页的刷新策略以及binlog在数据备份和一致性中的角色。同时,提到了日志管理对于数据库性能的影响和优化方法。
摘要由CSDN通过智能技术生成

只将事务执行过程产生的redo日志刷新到磁盘的好处

  • redo日志占用的存储空间非常小
  • redo日志是顺序写入磁盘的,顺序I/O

redo作用

Redo log的主要作用是用于数据库的崩溃恢复

redo做什么

redo log是InnoDB引擎特有的,只记录该引擎中表的修改记录。
binlog是MySQL的Server层实现的,会记录所有引擎对数据库的修改。
redo log是物理日志,记录的是在具体某个数据页上做了什么修改;binlog是逻辑日志,记录的是这个语句的原始逻辑。
redo log是循环写的,空间固定会用完;binlog是可以追加写入的,binlog文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。
redolog记录修改内容(哪一页发生了什么变化),写于事务开始前,用于数据未落磁盘,但数据库挂了后的数据恢复。
binlog记录修改SQL,写于事务提交时,可用于读写分离。
undolog记录修改前记录,用于回滚和多版本并发控制。

前滚和回滚

前滚: 未完全提交的事务,即该事务已经被执行commit命令了,只是现在该事务修改所对应的脏数据块中只有一部分被写到磁盘上的数据文件中,还有一部分已经被置为提交标记的脏块还在内存上。

如果此时数据库实例崩溃了,则当数据库实例恢复时,就需要用前滚(这个机制)来完成事务的完全提交,即将先前那部分已经被置为提交标记且还在内存上的脏块写入到磁盘上的数据文件中。

回滚: 未提交的事务,即该事务未被执行commit命令。但是此时,该事务修改的脏块中也有可能一部分脏块写入到数据文件中了。如果此时数据库实例崩溃了,则当数据库实例恢复时,就需要用回滚(这个机制)来将先前那部分已经写入到数据文件的脏块从数据文件上撤销掉。

redo log 是重做日志,提供 前滚 操作;undo log 是回退日志,提供 回滚 操作。
redo log保证事务的持久性,undo log保证事务的原子性。

redo的作用

记录的是尚未完成的操作,数据库崩溃则用其重做

redo的组成

Redo log可以简单分为以下两个部分:

  • 保存在内存中重做日志的缓冲 (redo log buffer),是易失的
  • 保存在硬盘中重做日志文件 (redo log file),是持久的

redo工作流程

在这里插入图片描述
InnoDB 的更新操作采用的是 Write Ahead Log (预先日志持久化)策略,即先写日志,再写入磁盘。
当一条记录更新时,redo流程大致如下

在内存更新数据后,会把更新后的记录写入到 redo log buffer 中。

第一步:InnoDB 会先把记录从硬盘读入内存
第二步:修改数据的内存拷贝
第三步:生成一条重做日志并写入redo log buffer,记录的是数据被修改后的值
第四步:当事务commit时,将redo log buffer中的内容刷新到 redo log file,对 redo log file采用追加写的方式
第五步:定期将内存中修改的数据刷新到磁盘中(注意注意注意,不是从redo log file刷入磁盘,而是从内存刷入磁盘,redo log file只在崩溃恢复数据时才用),如果数据库崩溃,则依据redo log buffer、redo log file进行重做,恢复数据,这才是redo log file的价值所在

redo是如何保证事务的持久性的呢

答案是Force Log at Commit 机制,即当事务commit提交时,innodb引擎先将 redo log buffer 写入到 redo log file 进行持久化,待事务的commit操作完成时才算完成。这种做法也被称为 Write-Ahead Log(预先日志持久化),在持久化一个数据页之前,先将内存中相应的日志页持久化。

问题1:为何不直接将修改的数据写入磁盘,而是要write ahead log呢?
答案:用于崩溃恢复
详解:
undo日志是对原始数据的备份
redo日志是对原始数据的修改
原始数据的按照既定的数据结构存放在磁盘上,写入磁盘是要耗费巨大成本的,而写入redo相对容易一些,因为redo里毕竟只需要考虑存放改动的数据即可,所以内存数据写写入redo log file,然后内存数据才能写入磁盘,如此,在内存数据再写入磁盘时因为某种原因比如断电崩溃,那么还可以依据redo log file恢复数据,如下图所示。

在这里插入图片描述

问题2:如何保证每次修改的数据都能写入redo log file呢?
储备知识1
O_DIRECT选项是在Linux系统中的选项,使用该选项后,对文件进行直接IO操作,不经过文件系统缓存,直接写入磁盘
储备知识2
redo log又称之为重做日志,因重做日志打开并没有O_DIRECT选项,所以重做日志先写入到文件系统缓存,然后才会刷入硬盘,即
Redo log buffer—>os cache(文件系统缓存)—>redo log file
如果在刷入redo log file前断电,则会丢失文件系统缓存中数据,数据未写入redo log file,
因为由内存写入redo log file在前,而由内存写入磁盘在后,所以redo log file写入失败,则数据丢失
那如何保证每次的修改都记入日志文件redo log file呢???
答案是fsync操作
在每次将redo buffer写入os cache文件系统缓存后,InnoDB存储引擎都需要调用一次 fsync操作,保证立即由os cache文件系统缓存写入redo log file
fsync是一种系统调用操作,其fsync的效率取决于磁盘的性能,因此磁盘的性能也影响了事务提交的性能,也就是数据库的性能。

问题3:脏页何时刷入磁盘呢?
储备知识:脏页
Buffer Pool 中更新的数据未刷新到磁盘中,该内存页我们称之为脏页。最终脏页的数据会刷新到磁盘中,将磁盘中的数据覆盖,这个过程与 redo log 不一定有关系。
答案
redo log 日志满了的情况下,会主动触发脏页刷新到磁盘

问题4:脏页只在redo log满的情况下才会刷入磁盘吗?
答案:no,以下几种情况同样会触发脏页的刷新

  • 1、系统内存不足时,需要将一部分数据页淘汰掉,如果淘汰的是脏页,需要先将脏页同步到磁盘;
  • 2、MySQL 认为空闲的时间,这种情况没有性能问题;
  • 3、MySQL 正常关闭之前,会把所有的脏页刷入到磁盘,这种情况也没有性能问题。

问题5:脏页刷入会带来性能问题吗?
在生产环境中,如果我们开启了慢 SQL 监控,你会发现偶尔会出现一些用时稍长的 SQL。这是因为脏页在刷新到磁盘时可能会给数据库带来性能开销, 导致数据库操作抖动。

Undo log

undo即撤销还原。

用于记录更改前的一份copy,在操作出错时,可以用于回滚、撤销还原,只将数据库逻辑地恢复到原来的样子

undo日志记录了什么?
比如有两个用户访问数据库,当然并发罗。A是更改,B是查询。

  • A更改还没有提交,B查询的话,数据肯定为历史数据,这个历史数据就是来源于UNDO段,

  • A更改未提交,需要回滚rollback,回滚rollback的数据也来至于UNDO段。

结论:为了并发时读一致性成功,那么DML操作,肯定先写UNDO段。

undo的存储位置

在InnoDB存储引擎中,undo存储在回滚段(Rollback Segment)中,每个回滚段记录了1024个undo log segment,而在每个undo log segment段中进行undo 页的申请,在5.6以前,Rollback Segment是在共享表空间里的,5.6.3之后,可通过 innodb_undo_tablespace设置undo存储的位置。

undo的类型

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

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

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

补充:purge线程两个主要作用是:清理undo页和清除page里面带有Delete_Bit标识的数据行。在InnoDB中,事务中的Delete操作实际上并不是真正的删除掉数据行,而是一种Delete Mark操作,在记录上标识Delete_Bit,而不删除记录。是一种"假删除",只是做了个标记,真正的删除工作需要后台purge线程去完成。

undo log 是否是redo log的逆过程?

其实从前文就可以得出答案了,undo log是逻辑日志,对事务回滚时,只是将数据库逻辑地恢复到原来的样子,而redo log是物理日志,记录的是数据页的物理变化,显然undo log不是redo log的逆过程。
在这里插入图片描述
MySQL数据库的数据备份、主备、主主、主从都离不开binlog,需要依靠binlog来同步数据,保证数据一致性

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值