Open log | Flush log | Open datafile | Flush data | |
Fdatasync | fsync() | fsync() | ||
O_DSYNC | O_SYNC | fsync() | ||
O_DIRECT | fsync() | O_DIRECT |
Fsync() |
fdatasync被认为是安全的,因为在MySQL总会调用fsync来flush数据。使用O_DSYNC是有些风险的,有些OS会忽略该参数O_SYNC。
我们看到O_DIRECT和fdatasync和很类似,但是它会使用O_DIRECT
来打开数据文件。有数据表明,如果是大量随机写入操作,O_DIRECT
会提升效率。但是顺序写入和读取效率都会降低。所以使用O_DIRECT需要谨慎。
mysql innodb 对应相关参数:
innodb_flush_method有三个值,分别是fdatasync,O_DSYNC和O_DIRECT,其中fdatasync是默认值。它们控制了InnoDB刷新日志和数据的模式。
fdatasync:InnoDB使用fsync()函数去更新日志和数据文件。
O_DSYNC:InnoDB使用O_SYNC模式打开并更新日志文件,用fsync()函数去更新数据文件。
O_DIRECT:InnoDB使用O_DIRECT模式打开数据文件,用fsync()函数去更新日志和数据文件。
我们看到O_DIRECT和fdatasync和很类似,但是它会使用O_DIRECT
来打开数据文件。有数据表明,如果是大量随机写入操作,O_DIRECT
会提升效率。但是顺序写入和读取效率都会降低。所以使用O_DIRECT需要谨慎。
其他相关知识:
Linux上的块设备的操作可以分为两类:
第一类是使用C标准库中的fopen/fread/fwrite 系列的函数,我们可以称其为 buffered I/O。具体的I/O path如下
Application<->Library Buffer<->Operation System Cache<->File System/Volume Manager<->Devicelibrary buffer是标准库提供的用户空间的buffer,可以通过setvbuf改变其大小。
第二类是使用Linux的系统调用的open/read/write 系列的函数,我们可以称其为 non-buffered I/O。I/O Path
Application<-> Operation System Cache <->File System/Volume Manager<->Device此外,我们可以通过设置open的O_DIRECT标志来实现Direct I/O(或者叫Raw I/O),即绕过OS Cache,直接读取Device ( that's what we want^o^ ), 等于将OS cache换成自己管理的cache。不过,Linus在邮件列表中建议不这么做,而是使用posix_fadvice, madvice。[2]中表明Direct I/O比buffered I/O的性能高很多。