MySQL InnoDB:WAL、Double Write Buffer、Log Buffer、Redo Log的区别

MySQL InnoDB: Differences between WAL, Double Write Buffer, Log Buffer, Redo Log

我正在学习 MySQL 架构。我想出了下面的例子:

有4个概念不太明白:

我看了很多文档,Write-Ahead Log (WAL) 是一种数据库持久化机制。 MySQL WAL Design Wikipedia WAL

如上图,从内存缓冲池刷数据到磁盘时有两种类型的缓冲区:双写缓冲区和日志缓冲区。为什么我们需要 2 个缓冲区,它们与 WAL 有什么关系?

最后但同样重要的是,重做日志和WAL有什么区别。我认为 WAL 可以在发生错误时帮助数据库恢复(例如:停电,服务器崩溃......)。除了 WAL,我们还需要什么重做日志?

您链接到的 WAL 设计文档提供了线索:

All the changes to data files are logged in the WAL (called the redo log in InnoDB).

这意味着 WAL 和重做日志是同一日志的两个不同术语。没有区别。

日志缓冲区是 RAM 中的分配。所有对redo log的写入都先保存在log buffer中,因为在RAM中保存一些数据是非常快的。事务可能由影响许多单独行的许多更改组成,并且为这些行中的每一行写入磁盘会太慢。因此,在通往重做日志的路上所做的更改首先保存在日志缓冲区中。周期性地,日志缓冲区中的一组更改被保存到磁盘,在重做日志中。这发生在:

  • 您提交交易
  • 日志缓冲区已满(日志缓冲区大小固定)
  • 无论日志缓冲区是否已满,每 1 秒一次

double-write 缓冲区具有完全不同的用途。它实际上是磁盘上而不是 RAM 中的 InnoDB 表空间的一部分(我认为术语 "buffer" 用于 RAM 和磁盘中的存储令人困惑)。

double-write 缓冲区的目的是防止部分页面写入导致数据损坏,同时修改的页面从 innodb 缓冲池复制到表空间。也就是说,如果 MySQL 服务器在 InnoDB 将给定页面写入磁盘时崩溃,它可能会部分覆盖磁盘上的页面。即使有重做日志,也无法恢复此页面。

因此 InnoDB 首先将每个页面写入称为双写缓冲区的表空间的一个小子集。一旦完成该页面的写入,它就可以将该页面再次保存到表空间中的正确页面。如果这部分失败,没关系,因为页面也已写入双写缓冲区。一旦页面被保存到表空间中的正确位置,双写缓冲区中该页面的副本就不需要了,下次从缓冲池刷新页面时可以覆盖它。