https://cloud.tencent.com/developer/article/1757612

为什么 redo log 具有 crash-safe 的能力,而 binlog 没有?

redo log 是什么?

一个固定大小,**“循环写”**的日志文件,记录的是物理日志——“在某个数据页上做了某个修改”。

binlog 是什么?

一个无限大小,**“追加写”**的日志文件,记录的是逻辑日志——“给 ID=2 这一行的 c 字段加1”。

redo log 和 binlog 有一个很大的区别就是,一个是循环写,一个是追加写。也就是说 redo log 只会记录未刷盘的日志,已经刷入磁盘的数据都会从 redo log 这个有限大小的日志文件里删除。binlog 是追加日志,保存的是全量的日志。

数据库 crash 后,想要恢复未刷盘但已经写入 redo log 和 binlog 的数据到内存时,binlog 是无法恢复的。虽然 binlog 拥有全量的日志,但没有一个标志让 innoDB 判断哪些数据已经刷盘,哪些数据还没有。

举个栗子,binlog 记录了两条日志:

  1. 给 ID=2 这一行的 c 字段加1
  2. 给 ID=2 这一行的 c 字段加1

在记录1刷盘后,记录2未刷盘时,数据库 crash。重启后,只通过 binlog 数据库无法判断这两条记录哪条已经写入磁盘,哪条没有写入磁盘,不管是两条都恢复至内存,还是都不恢复,对 ID=2 这行数据来说,都不对。