MySQL双写缓冲区(Doublewrite Buffer)深入解析

冯旭光 Lv4

1、什么是 Double write Buffer

​ Doublewrite Buffer 是 MySQL 数据库中 InnoDB 存储引擎的一种机制,用于解决部分写失效的问题,提高数据完整性和可靠性。Doublewrite Buffer 是内存 + 磁盘的结构,包括内存结构和磁盘结构两个部分。

  • 在内存结构中,Doublewrite Buffer 由 128 个页(Page)构成,大小是 2MB(128*16KB)。这些页在内存中以 Doublewrite Buffer 的形式存在。
  • 在磁盘结构中,Doublewrite Buffer 在系统表空间上是 128 个页(2个区,extend1 和 extend2),大小也是 2MB。这些页在磁盘上以 Doublewrite File 的形式存在。

Doublewrite Buffer 的原理是在将数据页写到数据文件之前,先将它们写入 Doublewrite Buffer 的共享表空间内。在完成写入 Doublewrite Buffer 后,再将数据页写入到数据文件的适当位置。这种方式可以确保数据的一致性和完整性,因为在写入过程中发生意外崩溃时,可以从 Doublewrite Buffer 中找到完好的数据页副本用于恢复。

![image-20250715103633520](../../images/articles/mysql/doublewrite buffer.png)

​ 当有数据页要被写入数据文件时,首先将页数据通过 memcpy 函数拷贝至内存中的 Doublewrite Buffer中。然后,Doublewrite Buffer 的内存中的数据页会刷写到 Doublewrite Buffer 的磁盘上,分两次写入磁盘共享表空间中(连续存储,顺序写,性能很高),每次写 1MB。完成 Doublewrite 页的写入之后,再将内存中的 Doublewrite Buffer 中的页写入到自己的表空间文件中。

​ 通过这种方式,至少在两次写操作中,数据文件和 Doublewrite Buffer 文件中至少有一份数据是正确无误的。如果写磁盘过程发生了崩溃,那么 MySQL 重启时可以通过校验和来确认是否有错误数据,如果 Doublewrite Buffer 文件错误了,就从数据文件中拉取原始数据根据 redo log 得出正确的目标数据,而如果数据文件错误了,则将 Doublewrite Buffer 中的数据重新写入数据文件。

2、Doublewrite Buffer 工作流程

  1. 写操作触发:当执行 INSERT、UPDATE 或 DELETE 等写操作时,MySQL 首先将数据写入双写缓冲区。
  2. 同步到 Doublewrite File:随后,双写缓冲区中的数据被同步(flush)到 Doublewrite File 中。这个过程是由后台线程完成的,以确保数据的持久性。
  3. 实际数据写入:一旦 Doublewrite File 中的数据被确认已经写入磁盘,MySQL 就可以将这些数据写入实际的数据文件中。
  4. 恢复机制:如果在写操作过程中发生故障,MySQL 可以从 Doublewrite File 中恢复数据。由于 Doublewrite File 中的数据是完整的,因此可以用来修复损坏的数据文件,确保数据的完整性和一致性。

3、为什么需要 Doublewrite Buffer

​ 从 MySQL 页(Page)和 Linux 页大小不同的角度来看,需要 Doublewrite Buffer 的原因主要是为了解决数据写入过程中的一致性和完整性问题。

​ 首先,我们需要了解 MySQL 的页和 Linux 的页大小不同。MySQL 的页通常大小为 16KB,而 Linux 的页大小可能因系统配置而有所不同,但常见的默认大小是 4KB。这意味着,当 MySQL 写入一个页的数据时,实际上是写入了一个更大的块,这个块可能跨越了多个 Linux 页。

考虑以下场景:

​ 假设 MySQL 正在写入一个页的数据,并且这个操作只完成了部分,比如只写了 50% 的数据。在这种情况下,如果直接将这个不完整的数据页写入数据文件,那么数据文件就会处于一个不一致的状态。某些查询可能会读取到这个不完整的数据页,导致数据损坏或不一致。

​ 为了解决这个问题,Doublewrite Buffer 被引入。当 MySQL 写入一个数据页时,首先会将整个页写入 Doublewrite Buffer。这样,即使写操作只完成了部分,Doublewrite Buffer 中的数据仍然是完整的。然后,Doublewrite Buffer 中的数据再被同步(flush)到实际的数据文件中。这样,即使发生故障,也可以从 Doublewrite Buffer 中恢复数据,确保数据的完整性和一致性。

综上所述,Doublewrite Buffer 的存在是为了解决由于 MySQL 页和 Linux 页大小不同导致的数据写入过程中的一致性和完整性问题。通过将数据先写入 Doublewrite Buffer,然后再同步到实际的数据文件,可以确保数据的完整性和一致性,避免因故障导致的数据损坏或不一致问题。

4、Doublewrite Buffer 的参数

MySQL 的双写缓冲区可以通过以下参数进行配置:

  • innodb_doublewrite:控制是否启用双写缓冲区的参数。可以设置为 ON 或 OFF。默认为 ON。
  • innodb_doublewrite_file:指定 Doublewrite File 的路径和文件名。默认值为 ib_logfile0 和 ib_logfile1。
  • innodb_doublewrite_buffer_size:控制双写缓冲区大小的参数。默认值是 256KB。可以根据需要进行调整,但不应设置得过大或过小,以免影响系统性能或导致不必要的内存占用。
  • 标题: MySQL双写缓冲区(Doublewrite Buffer)深入解析
  • 作者: 冯旭光
  • 创建于 : 2025-07-11 10:56:55
  • 更新于 : 2025-07-16 09:18:25
  • 链接: https://blog.fengxuguang.top/posts/280966a6/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论