只将事务执行过程产生的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 是回退日志,提供 回滚 操作。
- 1、事务的原子性、隔离性由锁机制实现,我们将在后续章节《数据库锁机制》中介绍
- 2、而事务的一致性和持久性由事务的 redo 日志和undo 日志来保证。redo log 是重做日志,提供再写入操作,实现事务的持久性;undo log 是回滚日志,提供回滚操作,保证事务的一致性。
redo的作用
记录的是尚未完成的操作,数据库崩溃则用其重做
redo的组成
Redo log可以简单分为以下两个部分:
- 保存在内存中重做日志的缓冲 (redo log buffer),是易失的
- 保存在硬盘中重做日志文件 (redo log file),是持久的
redo工作流程
InnoDB 的更新操作采用的是 Write Ahead Log (预先日志持久化)策略,即先写日志,再写入磁盘。
当一条记录更新时,redo流程大致如下
在内存更新数据后,会把更新后的记录写入到 redo log buffer 中。
redo是如何保证事务的持久性的呢
答案是Force Log at Commit 机制,即当事务commit提交时,innodb引擎先将 redo log buffer 写入到 redo log file 进行持久化,待事务的commit操作完成时才算完成。这种做法也被称为 Write-Ahead Log(预先日志持久化),在持久化一个数据页之前,先将内存中相应的日志页持久化。
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的逆过程。