5

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

在此处输入图像描述

有4个概念我不太理解:

  • 双写缓冲区
  • 日志缓冲区
  • 预写日志
  • 重做日志

我从许多文档中了解到,Write-Ahead Log (WAL) 是一种数据库持久性机制。MySQL WAL 设计 维基百科 WAL

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

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

4

1 回答 1

12

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

对数据文件的所有更改都记录在 WAL 中(在 InnoDB 中称为重做日志)。

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

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

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

双写缓冲区的用途完全不同。它实际上是磁盘上 InnoDB 表空间的一部分,而不是 RAM(我认为术语“缓冲区”用于存储在 RAM 和磁盘中是令人困惑的)。

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

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

于 2019-06-30T15:25:06.413 回答