Prewarming PostgreSQL I/O caches
cybertec-postgresql.com
cybertec-postgresql.com
If you have data that rarely changes you can actually create an ad-hoc database system based on that and have performance like an in memory database without having to worry much about the memory of the system.
If I understand correctly O_DIRECT (the usual flag of open(2)) is one of the possible behavior of WAL updates, precisely the 'wal_sync_method' setting ( https://www.postgresql.org/docs/11/runtime-config-wal.html ). Therefore it will indeed not let any data written by PG in the buffercache, but what about data _read_ (not written) by PG? The documentation lets me think that those data will, just after being read and without any specific disposition (posix_fadvise(2)...), be in the OS buffercache. (I didn't check PG's sourcecode).
By default we force the kernel's hand about when to write data back to disk from the page cache for a lot of the writes (from the checkpointing process and the background writer, but not by backends themselves - it can be enabled for backends too, and is often beneficial), as disk performance otherwise is quite unpredictable (with long stalls when the OS decides to trigger writeback).
For some workloads, in particular large and high read/write volume databases, it'd be very beneficial to support O_DIRECT for data too, but there's some work on postgres' IO subsystem needed to make that doable without performance regressions in a lot of scenarios.
Even once we add it, it's unlikely to become the default, at least for reads, as using O_DIRECT would require somewhat accurate tuning of postgres. Even for databases without high throughput. Whereas also utilizing the OS page cache doesn't require accurate sizing of shared_buffers etc, and adapts to changing workloads and global resource availability.
"pg_prewarm makes most sense if your database and your RAM are really really large (XXX GB or more)"
A benchmark preferably with databases of sizes that make sense.
Is there another case justifying a pre-fetching?
If I'm right pg_prewarm if not adequate with a SSD storage device, moreover "makes most sense if your database and your RAM are really really large" is sound as the amount of head moves is (typically) proportional to the DB size.
IMHO the most significant overall performance indicator here is the ratio R/D, where R is the size of the RAM available to PostgreSQL (mainly shared_buffers and the kernel buffercache), and D stands for the size of often used database objects (data, indices...).
Multiple runs of a benchmark in contexts where this ratio is 1, then 0.5, then 0.01... often produces interesting results.
Filling terabytes of memory from non-local storage (even if it is SSD) can take some time and benefits from parallel sequential readaheads instead of doing many small, random reads.
It can also be helpful when you have network attached storage (eg. EBS volume in AWS) since even if it is SSD you still have the network latency for each IO.
That's extremely common for index based accesses. Which in turn are a large fraction of queries in most use cases.
> If I'm right pg_prewarm if not adequate with a SSD storage device,
For SSDs random accesses and small accesses are still substantially slower than bulk reading data into memory.