Documentation Home
MySQL 8.3 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 40.8Mb
PDF (A4) - 40.9Mb
Man Pages (TGZ) - 294.0Kb
Man Pages (Zip) - 409.0Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb
Excerpts from this Manual

MySQL 8.3 Reference Manual  /  ...  /  Optimizing InnoDB Disk I/O

10.5.8 优化 InnoDB 磁盘 I/O

如果您遵循数据库设计的最佳实践和 SQL 操作的调整技术,但您的数据库仍然由于繁重的磁盘 I/O 活动而变慢,请考虑这些磁盘 I/O 优化。如果 Unix top 工具或 Windows 任务管理器显示您的工作负载的 CPU 使用率百分比小于 70%,那么您的工作负载可能是磁盘绑定的。

  • 增加缓冲池大小

    当表数据被缓存在 InnoDB 缓冲池中时,它可以被查询重复访问而不需要任何磁盘 I/O。使用 innodb_buffer_pool_size 选项指定缓冲池的大小。这个内存区域非常重要,以至于通常建议将 innodb_buffer_pool_size 配置为系统内存的 50% 到 75%。有关更多信息,请参阅 第 10.12.3.1 节,“MySQL 如何使用内存”

  • 调整刷新方法

    在某些版本的 GNU/Linux 和 Unix 中,使用 Unix fsync() 调用(InnoDB 默认使用)和类似方法来刷新文件到磁盘非常慢。如果数据库写入性能是一个问题,请使用 innodb_flush_method 参数设置为 O_DSYNC 进行基准测试。

  • 配置操作系统刷新阈值

    默认情况下,当 InnoDB 创建新的数据文件,例如新的日志文件或表空间文件时,该文件将完全写入操作系统缓存,然后刷新到磁盘,这可能会导致大量的磁盘写入活动同时发生。要强制较小、周期性的刷新操作系统缓存中的数据,可以使用 innodb_fsync_threshold 变量定义一个阈值,以字节为单位。当达到字节阈值时,操作系统缓存的内容将被刷新到磁盘。默认值为 0,强制默认行为,即仅在文件完全写入缓存后刷新到磁盘。

    指定阈值以强制较小、周期性的刷新可能有助于避免多个 MySQL 实例使用相同存储设备时的磁盘写入活动激增。例如,创建新的 MySQL 实例及其关联的数据文件可能会导致大量的磁盘写入活动,影响其他使用相同存储设备的 MySQL 实例的性能。配置阈值可以避免这种写入活动激增。

  • 使用 fdatasync() 而不是 fsync()

    在支持 fdatasync() 系统调用的平台上,innodb_use_fdatasync 变量允许使用 fdatasync() 而不是 fsync() 进行操作系统刷新。fdatasync() 系统调用不会刷新文件元数据的更改,除非需要用于后续数据检索,从而提供潜在的性能优势。

    某些 innodb_flush_method 设置,例如 fsyncO_DSYNCO_DIRECT,使用 fsync() 系统调用。innodb_use_fdatasync 变量适用于使用这些设置时。

  • 使用 noop 或 deadline I/O 调度程序与 Linux 本机 AIO

    InnoDB 使用 Linux 的异步 I/O 子系统(本机 AIO)来执行读取预读和写入请求数据文件页。该行为由 innodb_use_native_aio 配置选项控制,默认情况下启用。使用本机 AIO 时,I/O 调度程序的类型对 I/O 性能的影响更大。一般来说,noop 和 deadline I/O 调度程序是推荐的。请进行基准测试以确定哪个 I/O 调度程序为您的工作负载和环境提供了最好的结果。有关更多信息,请参阅 第 17.8.6 节,“在 Linux 上使用异步 I/O”

  • 在 Solaris 10 上使用直接 I/O,x86_64 架构

    使用 InnoDB 存储引擎在 Solaris 10 for x86_64 架构(AMD Opteron)上时,使用直接 I/O 来避免 InnoDB 性能下降。要使用直接 I/O 来整个 UFS 文件系统用于存储 InnoDB-related 文件,请使用 forcedirectio 选项挂载它;见 mount_ufs(1M)。(Solaris 10/x86_64 上的默认设置 使用该选项。)要仅将直接 I/O 应用于 InnoDB 文件操作,而不是整个文件系统,请设置 innodb_flush_method = O_DIRECT。使用该设置时,InnoDB 将调用 directio() 而不是 fcntl() 来执行数据文件的 I/O 操作(而不是日志文件的 I/O 操作)。

  • 使用原始存储来存储数据和日志文件,适用于 Solaris 2.6 及更高版本

    使用 InnoDB 存储引擎时,在 Solaris 2.6 及更高版本的任何平台(sparc/x86/x64/amd64)上,使用大型 innodb_buffer_pool_size 值时,进行基准测试,使用原始设备或直接 I/O UFS 文件系统,使用 forcedirectio 挂载选项,如前所述。(如果您想对日志文件使用直接 I/O,需要使用挂载选项,而不是设置 innodb_flush_method。)Veritas 文件系统 VxFS 的用户应该使用 convosync=direct 挂载选项。

    不要将其他 MySQL 数据文件,如 MyISAM 表文件,放在直接 I/O 文件系统上。可执行文件或库 不能 放在直接 I/O 文件系统上。

  • 使用附加存储设备

    可以使用附加存储设备来设置 RAID 配置。有关信息,请参阅 第 10.12.1 节,“优化磁盘 I/O”

    另外,InnoDB 表空间数据文件和日志文件可以放在不同的物理磁盘上。有关信息,请参阅以下部分:

  • 考虑非旋转存储

    非旋转存储通常提供了更好的随机 I/O 操作性能;旋转存储提供了更好的顺序 I/O 操作性能。当将数据和日志文件分布在旋转和非旋转存储设备上时,考虑每个文件上的 I/O 操作类型。

    随机 I/O 导向文件通常包括 每表文件通用表空间 数据文件、撤销表空间 文件和 临时表空间 文件。顺序 I/O 导向文件包括 InnoDB 系统表空间 文件、双写文件和日志文件,如 二进制日志 文件和 重做日志 文件。

    查看以下配置选项的设置时使用非旋转存储:

    • innodb_checksum_algorithm

      使用 crc32 选项,它使用更快的 checksum 算法,适用于快速存储系统。

    • innodb_flush_neighbors

      优化旋转存储设备的 I/O 操作。禁用它以用于非旋转存储或混合存储设备。默认情况下,它是禁用的。

    • innodb_idle_flush_pct

      允许在空闲期间限制页面刷新,以帮助延长非旋转存储设备的寿命。

    • innodb_io_capacity

      默认设置为 200 通常足以满足低端非旋转存储设备的需求。对于高端总线附加设备,考虑将其设置为 1000。

    • innodb_io_capacity_max

      默认值为 2000,旨在满足使用非旋转存储的工作负载。对于高端总线附加非旋转存储设备,考虑将其设置为 2500。

    • innodb_log_compressed_pages

      如果 redo 日志位于非旋转存储上,考虑禁用该选项以减少日志记录。请参阅 禁用压缩页面的日志记录

    • innodb_log_file_size (已弃用)

      如果 redo 日志位于非旋转存储上,配置该选项以最大化缓存和写入组合。

    • innodb_redo_log_capacity

      如果 redo 日志位于非旋转存储上,配置该选项以最大化缓存和写入组合。

    • innodb_page_size

      考虑使用与磁盘内部扇区大小匹配的页面大小。早期 SSD 设备通常具有 4KB 扇区大小。一些新设备具有 16KB 扇区大小。InnoDB 的默认页面大小为 16KB。将页面大小保持接近存储设备块大小,以最小化重写到磁盘的未更改数据量。

    • binlog_row_image

      如果二进制日志位于非旋转存储上且所有表具有主键,考虑将该选项设置为 minimal 以减少日志记录。

    确保操作系统中启用了 TRIM 支持。通常情况下,默认启用。

  • 增加 I/O 容量以避免积压

    如果由于 InnoDB 检查点 操作,吞吐量周期性下降,考虑增加 innodb_io_capacity 配置选项的值。较高的值会导致更频繁的 刷新,避免了可能导致吞吐量下降的工作积压。

  • 如果刷新不落后,降低 I/O 容量

    如果系统没有落后于 InnoDB 刷新 操作,考虑降低 innodb_io_capacity 配置选项的值。通常情况下,您可以将该选项值保持尽可能低,但不要太低,以免导致周期性吞吐量下降,如前一个bullet所述。在典型场景中,您可能会在 SHOW ENGINE INNODB STATUS 的输出中看到以下组合:

    • 历史列表长度低,少于几千。

    • 插入缓冲区合并接近插入的行数。

    • 缓冲池中的修改页面一致低于 innodb_max_dirty_pages_pct 的缓冲池百分比。(在服务器不执行批量插入时测量;在批量插入期间,修改页面百分比的增加是正常的。)

    • 日志序列号 - 最后检查点 小于日志文件的总大小的 7/8 或理想情况下小于 6/8。

  • 在 Fusion-io 设备上存储系统表空间文件

    您可以通过将包含双写缓存存储区域的文件存储在支持原子写入的 Fusion-io 设备上,利用双写缓存相关 I/O 优化。(双写缓存存储区域驻留在双写文件中。请参阅 第 17.6.4 节,“双写缓存”。)当双写缓存存储区域文件位于支持原子写入的 Fusion-io 设备上时,双写缓存将自动禁用,并使用 Fusion-io 原子写入所有数据文件。该功能仅在 Fusion-io 硬件上支持,并且仅在 Linux 上的 Fusion-io NVMFS 上启用。为了充分利用该功能,建议将 innodb_flush_method 设置为 O_DIRECT

    Note

    因为双写缓存设置是全局的,因此双写缓存也将禁用不在 Fusion-io 硬件上的数据文件。

  • 禁用压缩页面的日志记录

    使用 InnoDB 表的 压缩 功能时,当对压缩数据进行修改时,重新压缩的页面图像将被写入 重做日志 中。该行为由 innodb_log_compressed_pages 控制,默认情况下启用该功能,以防止在恢复期间使用不同版本的 zlib 压缩算法时可能出现的损坏。如果您确定 zlib 版本不会更改,可以禁用 innodb_log_compressed_pages 以减少修改压缩数据的工作负载的重做日志生成。