2013-10-18 27 views
5

我正在编写一个在Linux和FreeBSD上运行的程序,并且我想确保当每个write()返回时,数据实际写入物理设备上的文件,所以我的数据不会意外丢失(例如,电力丢失,过程意外中断等)。O_DIRECT与Linux/FreeBSD上的O_SYNC

根据OPEN(2)手册页,在Linux(高于2.6)上,O_DIRECT是同步的,但可能存在性能问题;在FreeBSD上,O_DIRECT不能保证同步,也可能有问题。

因此,在Linux上,O_DIRECTO_SYNC保证同步写入,但哪一个具有更好的性能?

在FreeBSD,以保证同步写入,该选项具有最佳性能:(1)O_DIRECT + fsync()(2)O_DIRECT | O_SYNC或(3)单独O_SYNC

+0

我认为你根本无法比较这些,因为它们是根本不同的东西(即使它们看起来像是做了类似的事情)。 – Damon

回答

5

对于当前的硬盘,有确保文件实际写入磁盘,即使磁盘向操作系统报告写入已完成!这是由于驱动器内置了缓存。

FreeBSD上,你可以通过kern.cam.ada.write_cache的sysctl设置为0,这禁用此将降低写入性能显著。我最后一次测量它(ICH-7芯片组上的WDC WD5001ABYS-01YNA0硬盘,FreeBSD 8.1 AMD64),连续写入性能(以dd if=/dev/zero of=/tmp/foo bs=10M count=1000测量)从75,000,000字节/秒降至12,900,000字节/秒。

如果您想确保您的文件已被写入,

  • 使用sysctl kern.cam.ada.write_cache=0后跟camcontrol reset <bus>:<target>:<lun>禁用写入缓存。
  • O_SYNC选项打开文件。

注:

  • 你写性能比较(在HDD)现在绝对吸。
  • 不要使用sync选项安装分区;这将导致所有 I/O(包括读取)同步完成。
  • 请勿使用O_DIRECT。它会尝试完全绕过缓存。这可能也会影响阅读。
3

O_DIRECT基本上只存在于Oracle以绕过内核的缓冲区缓存层并执行其自己的缓存。它有不明确的语义,可以执行的读取大小和对齐方式的任意限制,通常不应使用。 O_SYNC应该给你想要的效果,但是如果没有底层文件系统对电源故障或崩溃有效,它仍然可能不足以满足您的需求。

+0

谢谢。关于性能,哪一个性能更好,O_DIRECT还是O_SYNC? –

+0

除非你编写你自己的缓存层(甚至可能),'O_DIRECT'具有糟糕的性能,因为它每次都会从磁盘重新读取数据。 –

相关问题