Linux 设备IO 研究与数据库性能调优

数据库系统是基于文件系统的,其性能和设备读写的机制有密切的关系。

和数据库性能密切相关的文件I/O操作的三个操作:

open               打开文件

write              写文件

fdatasync       flush操作(将文件缓存刷到磁盘上)。

一、Open操作

open("test.file",O_WRONLY|O_APPDENT|O_SYNC))

系统调用Open会为该进程一个文件描述符fd。这里使用了O_WRONLY|O_APPDENT|O_SYNC打开文件:

  1. O_WRONLY表示我们以"写"的方式打开,告诉内核我们需要向文件中写入数据;
  2. O_APPDENT告诉内核以"追加"的方式写文件;
  3. O_DSYNC告诉内核,当向文件写入数据的时候,只有当数据写到了磁盘时,写入操作才算完成(write才返回成功)。
  4. 和O_DSYNC同类的文件标志,还有O_SYNC,O_RSYNC,O_DIRECT。
    • O_SYNC比O_DSYNC更严格,不仅要求数据已经写到了磁盘,而且对应的数据文件的属性(例如文件长度等)也需要更新完成才算write操作成功。可见O_SYNC较之O_DSYNC要多做一些操作。
    • O_RSYNC表示文件读取时,该文件的OS cache必须已经全部flush到磁盘了【附录3】
    • 如果使用O_DIRECT打开文件,则读/写操作都会跳过OS cache,直接在device(disk)上读/写。因为没有了OS cache,所以会O_DIRECT降低文件的顺序读写的效率。

二、Write操作

write(fd,buf,6)

在使用open打开文件获得文件描述符之后,我们就可以调用write函数来写入数据了,write会根据前面的open参数不同,而表现不同。

三、Flush阶段

fdatasync(fd) == -1

write操作后,我们还调用了fdatasync来确保文件数据flush到了disk上。fdatasync返回成功后,那么可以认为数据已经写到了磁盘上。像这样的flush的函数还有fsync、sync。

  1. Fsync和fdatasync的区别等同于O_SYNC和O_DSYNC的区别。
  2. Sync函数表示将文件在OS cache中的数据排入写队列,www.linuxidc.com并不确认是否真的写磁盘了,所以sync并不可以靠。

忽略文件打开的过程,通常我们会说“写文件”有两个阶段,一个是调用write我们称为写数据阶段(其实是受open的参数影响),调用fsync(或者fdatasync)我们称为flush阶段。

Linux上的块设备的操作可以分为两类:

第一类是使用C标准库中的fopen/fread/fwrite 系列的函数,我们可以称其为 buffered I/O。

具体的I/O path如下

Application<->Library Buffer<->Operation System Cache<->File System/Volume Manager<->Device

library buffer是标准库提供的用户空间的buffer,可以通过setvbuf改变其大小。

第二类是使用Linux的系统调用的open/read/write 系列的函数,我们可以称其为 non-buffered I/O。

I/O Path

Application<-> Operation System Cache <->File System/Volume Manager<->Device

相关推荐