1. 程式人生 > >Linux fflush 與 fsync的區別

Linux fflush 與 fsync的區別

在學習innodb_flush_method的方法時,看到下面的文章:

http://www.orczhou.com/index.php/2009/08/innodb_flush_method-file-io/

文章對此引數介紹的比較詳細。(摘錄其中一段。。。。)

引數Innodb_flush_method(Linux)可以設定為:Fdatasync、O_DSYNC、O_DIRECT。我們看看這個三個引數是如何影響程式MySQL對日誌和資料檔案的操作:

#mytable td{text-align:center}
Open log Flush log Open datafile Flush data
Fdatasync fsync() fsync()
O_DSYNC O_SYNC fsync()
O_DIRECT fsync() O_DIRECT Fsync()
Linux man page 上對open的O_SYNC的描述:
O_SYNC
The file is opened for synchronous I/O. Any write ()s on the resulting file descriptor will block the calling process until the data has been physically written to the underlying hardware. But see RESTRICTIONS below
.
Restrictions
There are many infelicities in the protocol underlying NFS, affecting amongst others O_SYNC and O_NDELAY .

POSIX provides for three different variants of synchronised I/O, corresponding to the flags O_SYNC , O_DSYNC and O_RSYNC . Currently (2.1.130) these are all synonymous under Linux.

Linux man page上對fflush,fsync,sync和fdatasync的解釋:

#include <stdio.h>

int fflush(FILE *stream);

Description

The function fflush() forces a write of all user-space buffered data for the given output or update stream via the stream's underlying write function. The open status of the stream is unaffected.

Notes
Note that fflush() only flushes the user space buffers provided by the C library. To ensure that the data is physically stored on disk the kernel buffers must be flushed too.

此時就需要用到fsync 或者sync函式。

#include <unistd.h>

void sync(void);


Description

sync() first commits inodes to buffers, and then buffers to disk.

#include <unistd.h>

int fsync(int fd);

int fdatasync(int fd);

Description

fsync() transfers ("flushes") all modified in-core data of (i.e., modified buffer cache pages for) the file referred to by the file descriptor fd to the disk device (or other permanent storage device) where that file resides. The call blocks until the device reports that the transfer has completed. It also flushes metadata information associated with the file (see stat(2)).

fsync 將檔案相關的所有更改都發送到disk device。 這個呼叫是阻塞的,直到disk通知此函式傳輸完成。此函式也會將該檔案的檔案資訊flush到disk。

Calling fsync() does not necessarily ensure that the entry in the directory containing the file has also reached disk. For that an explicit fsync() on a file descriptor for the directory is also needed.

fdatasync() is similar to fsync(), but does not flush modified metadata unless that metadata is needed in order to allow a subsequent data retrieval to be correctly handled. For example, changes to st_atime or st_mtime (respectively, time of last access and time of last modification; see stat(2)) do not not require flushing because they are not necessary for a subsequent data read to be handled correctly. On the other hand, a change to the file size (st_size, as made by say ftruncate(2)), would require a metadata flush.

The aim of fdatasync(2) is to reduce disk activity for applications that do not require all metadata to be synchronised with the disk.

fdatasync與fsync的區別在於fdatasync不會flush檔案的metadata資訊。這個是為了減少對磁碟的操作。。。

Notes
If the underlying hard disk has write caching enabled , then the data may not really be on permanent storage when fsync() / fdatasync() return.

When an ext2 file system is mounted with the sync option, directory entries are also implicitly synced by fsync().

On kernels before 2.4, fsync() on big files can be inefficient. An alternative might be to use the O_SYNC flag to open.