![](https://csdnimg.cn/release/download_crawler_static/87541565/bg4.jpg)
14、为什么需要 redo log?
redo log 主要用于 MySQL 异常重启后的一种数据恢复手段,确保了数据的一致性。
其实是为了配合 MySQL 的 WAL 机制。因为 MySQL 进行更新操作,为了能够快速响应,
所以采用了异步写回磁盘的技术,写入内存后就返回。但是这样,会存在 crash 后 内存数
据丢失的隐患,而 redo log 具备 crash safe 的能力。
15、为什么 redo log 具有 crash-safe 的能力,是 binlog 无法替代的?
第一点:redo log 可确保 innoDB 判断哪些数据已经刷盘,哪些数据还没有
redo log 和 binlog 有一个很大的区别就是,一个是循环写,一个是追加写。也就是说 redo
log 只会记录未刷盘的日志,已经刷入磁盘的数据都会从 redo log 这个有限大小的日志文
件里删除。binlog 是追加日志,保存的是全量的日志。
当数据库 crash 后,想要恢复未刷盘但已经写入 redo log 和 binlog 的数据到内存时,binlog
是无法恢复的。虽然 binlog 拥有全量的日志,但没有一个标志让 innoDB 判断哪些数据已
经刷盘,哪些数据还没有。
但 redo log 不一样,只要刷入磁盘的数据,都会从 redo log 中抹掉,因为是循环写!数据
库重启后,直接把 redo log 中的数据都恢复至内存就可以了。
第二点:如果 redo log 写入失败,说明此次操作失败,事务也不可能提交
redo log 每次更新操作完成后,就一定会写入日志,如果写入失败,说明此次操作失败,事
务也不可能提交。
redo log 内部结构是基于页的,记录了这个页的字段值变化,只要 crash 后读取 redo log 进
行重放,就可以恢复数据。
这就是为什么 redo log 具有 crash-safe 的能力,而 binlog 不具备。
16、当数据库 crash 后,如何恢复未刷盘的数据到内存中?
根据 redo log 和 binlog 的两阶段提交,未持久化的数据分为几种情况:
change buffer 写入,redo log 虽然做了 fsync 但未 commit,binlog 未 fsync 到磁盘,这部
分数据丢失。
change buffer 写入,redo log fsync 未 commit,binlog 已经 fsync 到磁盘,先从 binlog 恢
复 redo log,再从 redo log 恢复 change buffer。
change buffer 写入,redo log 和 binlog 都已经 fsync,直接从 redo log 里恢复。
17、redo log 写入方式?
redo log 包括两部分内容,分别是内存中的日志缓冲(redo log buffer)和磁盘上的日志文件
(redo log file)。
MySQL 每执行一条 DML 语句,会先把记录写入 redo log buffer(用户空间) ,再保存到
内核空间的缓冲区 OS-buffer 中,后续某个时间点再一次性将多个操作记录写到 redo log
file(刷盘) 。这种先写日志,再写磁盘的技术,就是 WAL。