### 15.6.4 双写缓冲区

双写缓冲区是一个存储区域，其中`InnoDB`在将页面写入到它们在`InnoDB`数据文件。如果存在操作系统、存储子系统或意外[**mysqld**](mysqld.html)在页面写入过程中退出进程，`InnoDB`可以在崩溃恢复期间从双写缓冲区中找到一个好的页面副本。

虽然数据被写入两次，但双写缓冲区不需要两倍的 I/O 开销或两倍的 I/O 操作。数据以一个大的顺序块写入双写缓冲区，单个`同步（）`调用操作系统（除非是`innodb_flush_method`被设定为`O_DIRECT_NO_FSYNC`）。

在 MySQL 8.0.20 之前，双写缓冲存储区位于`InnoDB`系统表空间。从 MySQL 8.0.20 开始，双写缓冲区存储区位于双写文件中。

为双写缓冲区配置提供了以下变量：

-   [`innodb_doublewrite`](innodb-parameters.html#sysvar_innodb_doublewrite)

    这[`innodb_doublewrite`](innodb-parameters.html#sysvar_innodb_doublewrite)变量控制是否启用双写缓冲区。在大多数情况下，它默认启用。要禁用双写缓冲区，请设置[`innodb_doublewrite`](innodb-parameters.html#sysvar_innodb_doublewrite)为 0 或启动服务器`--skip-innodb-doublewrite`.如果您更关心性能而不是数据完整性，请考虑禁用双写缓冲区，例如执行基准测试时可能就是这种情况。

    如果双写缓冲区位于支持原子写入的 Fusion-io 设备上，则会自动禁用双写缓冲区，并使用 Fusion-io 原子写入执行数据文件写入。但是，请注意，[`innodb_doublewrite`](innodb-parameters.html#sysvar_innodb_doublewrite)设置是全局的。当双写缓冲区被禁用时，所有数据文件都被禁用，包括那些不驻留在 Fusion-io 硬件上的文件。此功能仅在 Fusion-io 硬件上受支持，并且仅在 Linux 上为 Fusion-io NVMFS 启用。为了充分利用此功能，一个[`innodb_flush_method`](innodb-parameters.html#sysvar_innodb_flush_method)的设置`O_DIRECT`被推荐。

-   [`innodb_doublewrite_dir`](innodb-parameters.html#sysvar_innodb_doublewrite_dir)

    这[`innodb_doublewrite_dir`](innodb-parameters.html#sysvar_innodb_doublewrite_dir)变量（在 MySQL 8.0.20 中引入）定义了目录，其中`InnoDB`创建双写文件。如果未指定目录，则在[`innodb_data_home_dir`](innodb-parameters.html#sysvar_innodb_data_home_dir)目录，如果未指定，则默认为数据目录。

    哈希符号“#”会自动作为指定目录名称的前缀，以避免与模式名称冲突。但是，如果是 '.'、'#'。或 '/' 前缀在目录名中明确指定，井号 '#' 不作为目录名的前缀。

    理想情况下，doublewrite 目录应放置在可用的最快存储介质上。

-   [`innodb_doublewrite_files`](innodb-parameters.html#sysvar_innodb_doublewrite_files)

    这[`innodb_doublewrite_files`](innodb-parameters.html#sysvar_innodb_doublewrite_files)变量定义双写文件的数量。默认情况下，为每个缓冲池实例创建两个双写文件：一个刷新列表双写文件和一个 LRU 列表双写文件。

    刷新列表双写文件用于从缓冲池刷新列表中刷新的页面。刷新列表双写文件的默认大小是`InnoDB`页面大小\*双写页字节。

    LRU 列表双写文件用于从缓冲池 LRU 列表中刷新的页面。它还包含用于单页刷新的插槽。LRU 列表双写文件的默认大小是`InnoDB`页面大小\*(doublewrite pages + (512 / the number of buffer pool instances)) 其中 512 是为单页刷新保留的插槽总数。

    至少有两个双写文件。双写文件的最大数量是缓冲池实例数量的两倍。（缓冲池实例的数量由[`innodb_buffer_pool_instances`](innodb-parameters.html#sysvar_innodb_buffer_pool_instances)多变的。）

    Doublewrite 文件名具有以下格式：`#ib_*`页*大小\`\***`文件编号`*.dblwr`.例如，以下双写文件是为 MySQL 实例创建的，其`InnoDB 页面大小为 16KB 和单个缓冲池：

    ```
    #ib_16384_0.dblwr
    #ib_16384_1.dblwr
    ```

    这[`innodb_doublewrite_files`](innodb-parameters.html#sysvar_innodb_doublewrite_files)变量用于高级性能调整。默认设置应该适合大多数用户。

-   [`innodb_doublewrite_pages`](innodb-parameters.html#sysvar_innodb_doublewrite_pages)

    这[`innodb_doublewrite_pages`](innodb-parameters.html#sysvar_innodb_doublewrite_pages)变量（在 MySQL 8.0.20 中引入）控制每个线程的最大双写页数。如果没有指定值，[`innodb_doublewrite_pages`](innodb-parameters.html#sysvar_innodb_doublewrite_pages)设置为[`innodb_write_io_threads`](innodb-parameters.html#sysvar_innodb_write_io_threads)价值。此变量用于高级性能调整。默认值应该适合大多数用户。

-   [`innodb_doublewrite_batch_size`](innodb-parameters.html#sysvar_innodb_doublewrite_batch_size)

    这[`innodb_doublewrite_batch_size`](innodb-parameters.html#sysvar_innodb_doublewrite_batch_size)变量（在 MySQL 8.0.20 中引入）控制批量写入的双写页数。此变量用于高级性能调整。默认值应该适合大多数用户。

    从 MySQL 8.0.23 开始，`InnoDB`自动加密属于加密表空间的双写文件页面（请参阅[第 15.13 节，“InnoDB 静态数据加密”](innodb-data-encryption.html)）。同样，属于页压缩表空间的双写文件页也被压缩。因此，双写文件可以包含不同的页面类型，包括未加密和未压缩的页面、加密的页面、压缩的页面以及加密和压缩的页面。
