3 ms·
> (Postgres, as an example, relies on the OS to buffer writes.) We don't really buffer writes via the OS that much, most of them are buffered in postgres' inte
by anarazel 8y ago
> (Postgres, as an example, relies on the OS to buffer writes.)
We don't really buffer writes via the OS that much, most of them are buffered in postgres' internal buffer cache. We even force the kernel's hand to write out things earlier (otherwise there often are huge latency spikes). It's more reads where it's useful because it allows the OS to cache as much IO data as the current memory situation on the system makes sensible.
> > Modern filesystems already have journals - buggy reimplementions of journals in userland doesn't help anyone.
You end up with journals anyway. There's no way to be performant otherwise, because you'd do hundreds of tiny writes instead of a few bigger journal writes. Imagine if your 1-row / 3 index transaction would have to write out ~7 blocks.
- josephg 8y ago> You end up with journals anyway. There's no way to be performant otherwise, because you'd do hundreds of tiny writes instead of a few bigger journal writes. Imagine if your 1-row / 3 index transaction would have to write out ~7 blocks. We can make that fast by letting the OS / libc batch write transactions. Although if `write()` blocks until the batch commits & gets called in a loop we'd have a performance problem. Non-blocking APIs don't have that problem though. The guarantee I want is that every write moves the system between two states: (not written)->(written). It should be impossible to reach some third (partially written) state through disk failure or an inappropriate power loss.
- vidarh 8y ago> We can make that fast by letting the OS / libc batch write transactions. Those are two very different things, potentially. If the write traverse a userspace-kernel boundary, there is no way to make that fast for small writes. If the batching happens entirely userspace, but just in a standard implementation, then sure. But people tend to severely underestimate how expensive syscalls are.
- colanderman 8y ago> We can make that fast by letting the OS / libc batch write transactions. That's not the problem. (OSes already do this.) The problem is one of locality. (Data writes are spread out among many parts of the disk, causing many writes to be issued for any given transaction.) You get around this by (1) logging to a journal, then (2) batching many seconds worth of writes in the hopes that they touch fewer blocks than the sum of their parts (or, in the case of rotary media, that they can be ordered efficiently). You can't just "wait" for this to happen before responding to the client unless you like 5+ second service times. Which brings us back to the necessity of a journal, which, as I already stated, must be managed by the application because different applications require different features and control which the filesystem doesn't (and likely can't) expose.