PostgreSQL pain points
lwn.net
lwn.net
O_DIRECT can have a lot of benefits. However, while O_DIRECT may be simple to use by itself, the other design and implementation requirements that are indirectly dragged along are not trivial by any means. Consequently, you should not be using O_DIRECT unless you can manage the substantial indirect overhead in implementation. It turns off a lot of OS features most developers take for granted.
It turns off a lot of OS features most developers take for granted.
Yeah, like OS buffering. What else?
To use O_DIRECT effectively in Linux, at a minimum you need to write a buffer cache that is both fast and adaptive to workloads with proper cache replacement schedulers (no LRU crap), you need to write a complete I/O scheduler replacement (e.g. using io_submit and related interfaces) which is not portable at all, and you need to stop using almost all file system APIs (it interferes with the I/O scheduling bypass).
O_DIRECT is easy to use for very narrow cases. Taking advantage of it for anything slightly complicated in terms of file I/O usage and you bite off a lot more low-level implementation or the performance will actually be worse.
There is a need for an alternate API, but it's not like fsync is "broken" for the general case.
Ideally, the kernel would know the deadline by which the data should be committed, manage accordingly, and the fsync would be simply acknowledged rather than inspiring extra IO.
This is pretty hard to work towards and the clearly specified narrow syscall interface leads to a great deal of difficulty in sharing this information with the kernel IO scheduling -- the way it is shared would naturally depend on the details of the kernel implementation, which would imply a tighter link between application and kernel version than is normally desirable.
Async w/O_DIRECT is the correct approach, despite the complexity. The problem is handling table scans that exploit system buffer cache for read-ahead. The answer to that is to issue more i/os to bigger buffers, or to a set of buffers. Scatter-gather disk i/o would help with that.
It might be particularly sweet if well-behaved applications could rely on mixing O_DIRECT with bufferd i/o on the same files. That is, all writes done O_DIRECT on pages read with O_DIRECT, and reads might be done against page-cached buffered files.