innodb_flush_method=O_DIRECT vs O_DSYNC 对带有 LVM 磁盘分区的 ext3 的性能影响

Gop*_*ath 14 mysql innodb performance mysql-5.1 redhat

在我的一个生产环境中,我们有两个实例在 RedHat 集群上运行,其中一个生产实例与该集群关联。

我们有 125G 主内存,24G InnoDB 缓冲池被 instance1 占用,12G 被 instance2 占用,这与 RedHat 集群无关。数据和事务日志都位于具有 ext3 文件系统的 LVM 磁盘分区上。

为了提高性能和更好的 I/O 吞吐量,我决定更改innodb_flush_methodO_DIRECT.

参考 MySQL 文档:

InnoDB 数据和日志文件位于 SAN 上,我们发现设置innodb_flush_methodO_DIRECT会使简单SELECT语句的性能降低三倍。

提到高性能 MySQL Ver 2 和 3,它表示 InnoDB 开发人员发现使用innodb_flush_method=O_DSYNC. O_SYNCandO_DSYNC类似于fsync()and fdatasync()O_SYNC同步数据和元数据,而O_DSYNC只同步数据。

如果这一切看起来像是没有建议的很多解释,那么建议如下:

如果您使用类 Unix 操作系统并且您的 RAID 控制器具有电池供电的写入缓存,我们建议您使用O_DIRECT. 如果没有,O_DIRECT根据您的应用程序,默认值或可能是最佳选择。

通过谷歌搜索,我得到了这个基准报告:on O_DSYNCvsO_DIRECT

基准报告:
====================
1B 行复杂事务测试,64 个线程

 * SAN O_DIRECT:读/写请求:31560140(每秒 8766.61 次)
 * SAN O_DSYNC:读/写请求:5179457(每秒 1438.52 次)
 * SAN fdatasync:读/写请求:9445774(每秒 2623.66 次)
 * 本地磁盘 O_DIRECT:读/写请求:3258595(每秒 905.06 次)
 * 本地磁盘 O_DSYNC:读/写请求:3494632(每秒 970.65 次)
 * 本地磁盘 fdatasync:读/写请求:4223757(每秒 1173.04 次。

但是,O_DIRECT禁用操作系统级缓存,其中可以禁用双缓存以显示更好的 I/O 吞吐量。

O_DIRECT而不是一起去O_DSYNC好吗?这两个选项有点混乱。哪个选项可以显示更好的 I/O 吞吐量和性能增强,而不会对数据、读/写产生任何影响,尤其是在生产中?根据您的个人经验有更好的建议吗?

我可以在帖子中看到 Rolando 更新:

这两个参数仍然存在轻微的混淆。在我可以看到大多数使用 的生产配置模板的地方O_DIRECT,我没有看到任何推荐O_DSYNC.

系统

  • MySQL 5.1.51-enterprise-gpl-pro-log
  • 红帽企业 Linux 服务器 5.5 版
  • 带 Raid 控制器的 DELL DRAC 具有电池回写缓存 512MB
  • Dell PERC 控制器 H700 带有电池备份单元 (BBU)。

附加信息

mysql> 显示诸如“innodb_thread_concurrency”之类的变量; 

+----------------------------+-------+
| 变量名 | 价值 |
+----------------------------+-------+ 
| innodb_thread_concurrency | 96 |
+----------------------------+-------+ 
1 行(0.00 秒) 

mysql> 显示变量,如“innodb_read_io_threads”; 
空集(0.00 秒) 

mysql> 显示变量,如“innodb_write_io_threads”; 
空集(0.00 秒)

我们使用的是默认插件,所以我发布了 InnoDB 状态的信息:

mysql> SELECT * FROM Plugins WHERE PLUGIN_NAME LIKE '%innodb%' AND PLUGIN_TYPE LIKE 'STORAGE ENGINE'\G
**************************** 1. 行 ******************** *******
           PLUGIN_NAME:InnoDB
        插件版本:1.0
         PLUGIN_STATUS:活动
           PLUGIN_TYPE:存储引擎
   PLUGIN_TYPE_VERSION:50151.0
        PLUGIN_LIBRARY:空
PLUGIN_LIBRARY_VERSION: NULL
         PLUGIN_AUTHOR:Innobase OY
    PLUGIN_DESCRIPTION:支持事务、行级锁定和外键
        PLUGIN_LICENSE: GPL
1 行(0.00 秒)

Rol*_*DBA 8

回到 2009 年 1 月 21 日,Peter Zaitsev 在mysqlperformanceblog.com上陈述了以下内容

作为行动呼吁——我肯定希望有人看看 EXT3 是否可以在这方面得到修复,因为它是迄今为止 Linux 最常见的文件系统。还值得研究一下是否可以在 MySQL 端做一些事情——O_DSYNC如果sync_binlog=1不使用 fsync 会有帮助,可能会用标志打开 binlog吗?或者可能是 binlog 预分配将是一个很好的解决方案。

到目前为止,我知道没有人接触过这个问题。O_DSYNC作为默认值不是一个吸引人的前景,但确实可以容纳未经真正验证的更快写入。这就是为什么有如此多的炒作O_DIRECT

我可以告诉你没有安装 InnoDB 插件。使用 InnoDB 插件,应该存在几个变量。

您应该通过以下两种方式之一升级 InnoDB:

  • 升级到 MySQL 5.5(所有 InnoDB 插件增强都是 MySQL 5.5 的一部分)
  • 升级 InnoDB 插件

完成后,您可以将 InnoDB 增强为

  • 访问更多 CPU 和内核
  • 增加读写I/O线程
  • 扩展 I/O 容量(这对于不同的存储介质尤其需要)

这是我过去关于您可以为此更改的设置的帖子:


小智 1

我一直认为这样O_DIRECT可以提高性能,因为它可以防止双缓冲。另外,前提是您有带有电池支持的写入缓存的硬件 RAID。当然,这也取决于工作负载,无论你是读重还是写重。

另外,向专家提出问题:对 for 的额外调用是否会fsync()导致O_DIRECT整体性能明显下降,还是可以忽略不计?我还没有看到基准测试表明这一点。

另请注意,Percona 启用了 set 的功能innodb_flush_method=ALL_O_DIRECT,它不仅可以在 InnoDB 数据文件上提供直接 I/O,还可以同时在 InnoDB 事务日志上提供直接 I/O。

  • 早在 2012 年,缓冲池就无法很好地适应巨大的 RAM,因此提到的双缓冲可能适用于操作系统缓存比 innodb 缓冲池大得多的情况。至于 5.6 及以上 - 我说你的答案是完全有效的。 (2认同)