双写缓冲区是一个存储区域,InnoDB
将从缓冲池中刷新的页面写入该区域,然后再将页面写入其在 InnoDB
数据文件中的正确位置。如果在页面写入过程中出现操作系统、存储子系统或意外的 mysqld 进程退出,InnoDB
可以在崩溃恢复期间从双写缓冲区找到该页面的良好副本。
虽然数据被写入两次,但双写缓冲区不需要两倍的 I/O 开销或两倍的 I/O 操作。数据被写入到双写缓冲区中一个大的连续块,使用对操作系统的单个 fsync()
调用(除非 innodb_flush_method
设置为 O_DIRECT_NO_FSYNC
)。
双写缓冲区存储区域位于双写文件中。
提供以下变量用于双写缓冲区配置
innodb_doublewrite
变量控制是否启用双写缓冲区。在大多数情况下,它默认启用。要禁用双写缓冲区,请将innodb_doublewrite
设置为OFF
。如果更关心性能而不是数据完整性,例如执行基准测试时,可以考虑禁用双写缓冲区。innodb_doublewrite
支持DETECT_AND_RECOVER
和DETECT_ONLY
设置。DETECT_AND_RECOVER
设置与ON
设置相同。使用此设置,双写缓冲区将完全启用,数据库页面内容将写入双写缓冲区,并在恢复期间访问该内容以修复不完整的页面写入。使用
DETECT_ONLY
设置,只有元数据被写入双写缓冲区。数据库页面内容不会写入双写缓冲区,恢复也不会使用双写缓冲区来修复不完整的页面写入。此轻量级设置旨在仅检测不完整的页面写入。MySQL 支持在启用双写缓冲区的
innodb_doublewrite
设置之间进行动态更改,包括ON
、DETECT_AND_RECOVER
和DETECT_ONLY
。MySQL 不支持在启用双写缓冲区的设置和OFF
之间进行动态更改,反之亦然。如果双写缓冲区位于支持原子写入的 Fusion-io 设备上,则会自动禁用双写缓冲区,并将数据文件写入使用 Fusion-io 原子写入来代替。但是,请注意
innodb_doublewrite
设置是全局的。当禁用双写缓冲区时,它将被禁用所有数据文件,包括不在 Fusion-io 硬件上的数据文件。此功能仅在 Fusion-io 硬件上受支持,并且仅为 Linux 上的 Fusion-io NVMFS 启用。为了充分利用此功能,建议将innodb_flush_method
设置为O_DIRECT
。innodb_doublewrite_dir
变量定义InnoDB
创建双写文件的目录。如果未指定目录,则双写文件将在innodb_data_home_dir
目录中创建,该目录默认为未指定时的数据目录。哈希符号 '#' 将自动添加在指定的目录名称前,以避免与模式名称冲突。但是,如果在目录名称中明确指定了 '.'、'#' 或 '/' 前缀,则不会在目录名称前添加哈希符号 '#'。
理想情况下,双写目录应放置在可用的最快存储介质上。
变量
innodb_doublewrite_files
定义了双写文件的数量,默认值为 2。默认情况下,每个缓冲池实例会创建两个双写文件:一个刷新列表双写文件和一个 LRU 列表双写文件。刷新列表双写文件用于从缓冲池刷新列表中刷新的页面。刷新列表双写文件的默认大小为
InnoDB
页面大小 * 双写页面字节数。LRU 列表双写文件用于从缓冲池 LRU 列表中刷新的页面。它还包含用于单页面刷新的插槽。LRU 列表双写文件的默认大小为
InnoDB
页面大小 * (双写页面 + (512 / 缓冲池实例数)),其中 512 是为单页面刷新保留的插槽总数。至少有两个双写文件。双写文件的最大数量是缓冲池实例数量的两倍。(缓冲池实例的数量由变量
innodb_buffer_pool_instances
控制。)双写文件的名称格式如下:
#ib_
(或page_size
_file_number
.dblwr.bdblwr
,使用DETECT_ONLY
设置)。例如,对于具有 16KB 的InnoDB
页面大小和单个缓冲池的 MySQL 实例,将创建以下双写文件。#ib_16384_0.dblwr #ib_16384_1.dblwr
变量
innodb_doublewrite_files
用于高级性能调整。默认设置应适用于大多数用户。变量
innodb_doublewrite_pages
控制每个线程的最大双写页面数。此变量用于高级性能调整。默认值应适用于大多数用户。
InnoDB
自动加密属于加密表空间的双写文件页面(参见 第 17.13 节,“InnoDB 数据静止加密”)。同样,属于页面压缩表空间的双写文件页面也会被压缩。因此,双写文件可能包含不同的页面类型,包括未加密和未压缩的页面、加密页面、压缩页面以及同时加密和压缩的页面。