注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Inside MySQL

MySQL MariaDB InnoDB InnoSQL

 
 
 

日志

 
 
关于我

MySQL技术内幕系列作者, 网易杭州研究院MySQL技术经理, 擅长于MySQL performance tuning、troubleshooting、systems availability and scalability、capacity planning

网易考拉推荐

InnoDB O_DIRECT选项漫谈(二)  

2013-07-15 18:58:29|  分类: InnoDB |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
前一篇中已经解释了InnoDB存储引擎为什么即使在开启O_DIRECT选项后依然需要调用fsync操作。本篇将说明MySQL 5.6中InnoDB存储引擎的变化以及O_DIRECT对重做日志文件的影响。

从MySQL 5.6的版本开始,也就是InnoDB 1.2版本中(PS:MariaDB 10.x版本将集成InnoDB 1.2版本),对于参数innodb_flush_method提供了一个新的设置值O_DIRECT_NO_FSYNC。在该参数设置下,InnoDB存储引擎将依然使用O_DIRECT选项打开数据表空间文件,但是在刷新时,不再需要需要额外的fsync操作。见官方手册中的说明:

An alternative setting is O_DIRECT_NO_FSYNC: it uses the O_DIRECT flag during flushing I/O, but skips thefsync() system call afterwards. This setting is suitable for some types of filesystems but not others. For example, it is not suitable for XFS. If you are not sure whether the filesystem you use requires anfsync(), for example to preserve all file metadata, use O_DIRECT instead.

然而,官方仅说明使用xfs文件系统不能设置为O_DIRECT_NO_FSYNC,但却只字未提哪个文件系统可以设置?请问MySQL官方这样的说明又有何意义呢?reiserfs和btrfs貌似(不十分确定)不使用inode来存放元数据信息,或许这两个文件系统下可以进行O_DIRECT_NO_FSYNC的设置?这个问题留给文件系统专家来回答了InnoDB O_DIRECT选项漫谈(二) - insidemysql - Inside MySQL。不过目前看来,最为安全和稳妥的做法还是将参数innodb_flush_method设置为O_DIRECT。

继续深入思考一个问题,为什么InnoDB的重做日志不使用O_DIRECT标识进行打开,而依然使用buffered I/O呢?我的理解是为了更为有效的Group Commit。若深入源码内部来看事务提交时的操作,InnoDB存储引擎的处理方式:

lock log->mutex
copy last redo log block to a new block 
write redo log buffer to disk
unlock log->mutex
fsync redo log files

可以看到fsync操作是在释放log->mutex之后。这样做的目的是在fsync时,由于已经释放log->mutex,那么其他事务可以继续将重做日志条目写入到redo log buffer中,同时这也是为什么在事务提交时,InnoDB会拷贝最后一个redo log block。若重做日志使用O_DIRECT,写入重做日志文件的过程会变慢(因为不是仅写入到操作系统缓存),Group Commit的效率就会变差。

Mark Callaghan尝试过以O_DIRECT的方式打开重做日志(http://www.facebook.com/note.php?note_id=10150219759210933),结果如下所示:

Results for all_direct are better at low-concurrency and O_DIRECT is faster for 4 or more concurrent connections.


   1       2       4       8      16      32      64    128

1952    2777    3530    3755    3829    3741    3760    3803  all_direct

1608    2479    3507    4541    4550    4644    4698    4581  O_DIRECT

Mark Callaghan只是给出了测试的结果,但是并没有说明问题的原因。根据Mark的测试环境,我想这就是因为Group Commit效率问题所致。Percona版本提供了ALL_O_DIRECT来设置重做日志的打开标识,但是根据我的研究,这是没有必要的,用户也不需要过于迷信该参数。

MySQL 5.6开始InnoDB可以将重做日志文件组设置为最大512G,之前的限制为4G。这对SSD和写入密集型应用会带来明显的帮助。但是重做日志buffered I/O的问题是会导致使用过多的操作系统缓存,这也是为什么Mark会想到使用O_DIRECT的方式来打开重做日志。

既然不能在InnoDB内部处理该问题(至少目前),我想可以通过操作系统提供的接口来刷新操作系统中缓存的数据,从而减少内存过度的使用问题。例如:

sysctl -w vm.drop_caches = 3

关于O_DIRECT的话题暂时结束了,希望用户能更好的理解其对InnoDB内部的影响。后续我将继续关注O_DIRECT_NO_FSYNC对于其他文件系统的影响。

-- EOF --

PS:欢迎关注InsideMySQL公众帐号
InnoDB O_DIRECT选项漫谈(二) - insidemysql - Inside MySQL
 
 
  评论这张
 
阅读(1549)| 评论(1)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017