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

Trầ*_* Dự 4 mysql innodb database-engine

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

在此处输入图片说明

有4个我不太理解的概念:

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

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

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

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

Bil*_*win 8

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

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

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

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

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

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

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

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

  • 感谢您非常详细的回答。我还有一个问题:如果在提交事务之前保存了重做日志/写缓冲区日志,那么事务被恢复,mysql如何处理?这不在我的问题范围内,但如果我能在其他地方得到答案,我会很高兴。 (2认同)
  • 您读过 https://dev.mysql.com/doc/refman/8.0/en/innodb-multi-versioning.html 吗? (2认同)
  • 您可能还想阅读[High Performance MySQL](http://shop.oreilly.com/product/0636920022343.do),这是一本写得很好的书,涵盖了很多这些概念。我曾经为作家工作过。 (2认同)