从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_flush_method设置为O_DIRECT。
可以看到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对于其他文件系统的影响。
前一篇中已经解释了InnoDB存储引擎为什么即使在开启O_DIRECT选项后依然需要调用fsync操作。本篇将说明MySQL 5.6中InnoDB存储引擎的变化以及O_DIRECT对重做日志文件的影响。
O_
DI
RECT
和O_SYNC是系统调用open的flag参数。通过指定open的flag参数,以特定的文件描述符打开某一文件。
这两个flag会对写盘的性能有很大的影响,因此对这两个flag做一些详细的了解。
先看一个open函数的使用例子.
/* Open new or existin
Di
rect
IO(O_
DI
RECT
) 详解
文章目录
Di
rect
IO(O_
DI
RECT
) 详解什么是
Di
rect
IO如何使用
Di
rect
IO
Di
rect
IO的性能
Di
rect
IO的应用
什么是
Di
rect
IO
Di
rect
IO也叫无缓冲IO,裸IO(rawIO),意思是使用无缓冲IO对文件进行读写,不会经过OS Cache。
通常,我们使用的文件流读取、内存映射都属于Cache IO,因为将数据写入文件,首先会写入cache,最终再落盘到IO device 或者称为
di
sk上。cache IO使得我们在
本篇文章主要是教大家如何在Linux系统里对数据库及设备IO库进行调优,相信对于Linux的初学者来说会有很大的帮助!
数据库系统是基于文件系统的,其性能和设备读写的机制有密切的关系。和数据库性能密切相关的文件I/O操作的三个操作:
open 打开文件
write 写文件
fdatasync
flush
操作(将文件缓存刷到磁盘上)。
一、Open操作
open(
Facebook的Mark大神最近一直在测试5.6的性能,并且发现了不少问题. 看来Facebook是要跳过5.5,直接上5.6了。同为互联网行业,Facebook的许多需求和我们是类似的,online ddl, 热点数据更新问题等。。。
当然,我最关注的还是5.6存在的bug。
related blog:
http://mysqlha.blogsp...
背景与目标
使用O_
DI
RECT
模式打开文件,然后用pread64和pwrite64直接读写文件。由于磁盘本身也可以看做一个文件,因此open打开文件或者磁盘都是同样适用的。
采用O_RDWR | O_
DI
RECT
对文件进行打开,关键点在于O_
DI
RECT
,表示不经过磁盘自带的缓存,直接对磁盘进行读写,在使用pread64和pwrite64时要求buffer的起始地址是4K对齐的,否则会失败,另外offset的偏移地址要求是512的整数倍,详细介绍可以看下面的参考资料。
pread64和p
本文来自:http://insidemysql.blog.163.com/blog/static/2028340422013671186977/
最近和文件系统内核开发人员做技术交流,对O_
DI
RECT
选项
有了新的认识。
在
InnoDB
存储引擎的配置中参数
innodb
_
flush
_
method
通常设置为O_
DI
RECT
,这也是官方文档所推荐的设置值。DBA或开发人员 知道该参...
mysql的
innodb
_
flush
_
method
有三种配置模式:
fdatasync模式:写数据时,write这一步并不需要真正写到磁盘才算完成(可能写入到操作系统buffer中就会返回完成),真正完成是
flush
操作,buffer交给操作系统去
flush
,并且文件的元数据信息也都需要更新到磁盘。
O_DSYNC模式:写日志操作是在write这步完成,而数据文件的写入是在
flush
这步通过fsync完成
O_
DI
RECT
模式:数据文件的写入操作是直接从mysql
innodb
buffer到磁盘的,并不用
Grafana导入 json 文件的 dashboard 错误 Templating Failed to upgrade legacy queries Datasource xxx not found
Buffer Pool Size of Total RAM No data
events_statements_summary_by_digest 未正常记录分类sql