文档首页
MySQL 9.0 参考手册
相关文档 下载本手册
PDF (US Ltr) - 40.0Mb
PDF (A4) - 40.1Mb
手册页 (TGZ) - 258.2Kb
手册页 (Zip) - 365.3Kb
信息 (Gzip) - 4.0Mb
信息 (Zip) - 4.0Mb


MySQL 9.0 参考手册  /  ...  /  优化 InnoDB 磁盘 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_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 变量适用。

  • 在 Linux 上使用 noop 或 deadline I/O 调度程序和原生 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 上对 x86_64 架构使用直接 I/O

    在 x86_64 架构(AMD Opteron)的 Solaris 10 上使用 InnoDB 存储引擎时,请对与 InnoDB 相关的文件使用直接 I/O,以避免 InnoDB 性能下降。要对用于存储与 InnoDB 相关文件的整个 UFS 文件系统使用直接 I/O,请使用 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 或更高版本的数据和日志文件

    在任何 Solaris 2.6 及更高版本以及任何平台(sparc/x86/x64/amd64)上使用具有较大 innodb_buffer_pool_size 值的 InnoDB 存储引擎时,请对原始设备或单独的直接 I/O UFS 文件系统上的 InnoDB 数据文件和日志文件进行基准测试,并使用前面描述的 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 选项使用更快的校验和算法,建议用于快速存储系统。

    • innodb_flush_neighbors

      优化旋转存储设备的 I/O。对于非旋转存储或旋转存储和非旋转存储的混合,请禁用它。默认情况下禁用它。

    • innodb_idle_flush_pct

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

    • innodb_io_capacity

      默认设置 10000 通常就足够了。

    • innodb_io_capacity_max

      默认值(2 * innodb_io_capacity)适用于大多数工作负载。

    • innodb_log_compressed_pages

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

    • innodb_log_file_size(已弃用)

      如果重做日志位于非旋转存储上,请配置此选项以最大限度地提高缓存和写入组合。

    • innodb_redo_log_capacity

      如果重做日志位于非旋转存储上,请配置此选项以最大限度地提高缓存和写入组合。

    • 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 配置选项的值。通常,您应尽可能地降低此选项值,但不要低到会导致前面提到的吞吐量周期性下降。在您可以降低选项值的典型情况下,您可能会在 SHOW ENGINE INNODB STATUS 的输出中看到如下组合

    • 历史记录列表长度较低,低于几千。

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

    • 缓冲池中的已修改页面始终远低于缓冲池的 innodb_max_dirty_pages_pct。(在服务器未执行批量插入时测量;在批量插入期间,已修改页面的百分比显着上升是正常的。)

    • 日志序列号 - 上次检查点 位于 InnoDB 日志文件 总大小的 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

    注意

    由于双写缓冲区设置是全局的,因此对于不驻留在 Fusion-io 硬件上的数据文件,也会禁用双写缓冲区。

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

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