Re: AIO v2.5
Tomas Vondra <tomas@vondra.me>
Commits
GET /api/v1/messages/:b64id/commits
the thread's linked commits as JSON, with link sources.
API reference →
-
aio: Fix assertion, clarify README
- 7b98c5536818 18.0 landed
- d3f97fd1dda3 19 (unreleased) landed
-
aio: Fix reference to outdated name
- f20a347e1a61 19 (unreleased) landed
- 95163cbe111c 18.0 landed
-
aio: Fix possible state confusions due to interrupt processing
- acad909321a4 18.0 landed
-
aio: Improve debug logging around waiting for IOs
- 039bfc457e43 18.0 landed
-
aio: Fix crash potential for pg_aios views due to late state update
- 0d9114b7040d 18.0 landed
-
Increase BAS_BULKREAD based on effective_io_concurrency
- 15f0cb26b530 18.0 landed
-
localbuf: Add Valgrind buffer access instrumentation
- 8ab4241b9f4f 18.0 landed
-
aio: Make AIO more compatible with valgrind
- 8e293e689bab 18.0 landed
-
aio: Avoid spurious coverity warning
- 57dec20fd469 18.0 landed
-
tests: Fix incompatibility of test_aio with *_FORCE_RELEASE
- a6285b150ad3 18.0 landed
-
tests: Cope with WARNINGs during failed CREATE DB on windows
- 43dca8a11624 18.0 landed
-
aio: Add errcontext for processing I/Os for another backend
- b3219c69fc1e 18.0 landed
-
aio: Add README.md explaining higher level design
- fdd146a8ef2b 18.0 landed
-
aio: Minor comment improvements
- e19dc74491e6 18.0 landed
-
aio: Add test_aio module
- 93bc3d75d8e1 18.0 landed
-
aio: Add pg_aios view
- 60f566b4f243 18.0 landed
-
docs: Add acronym and glossary entries for I/O and AIO
- 46250cdcb037 18.0 landed
-
Enable IO concurrency on all systems
- 2a5e709e721c 18.0 landed
-
read_stream: Introduce and use optional batchmode support
- ae3df4b34155 18.0 landed
-
docs: Reframe track_io_timing related docs as wait time
- b27f8637ea70 18.0 landed
-
bufmgr: Use AIO in StartReadBuffers()
- 12ce89fd0708 18.0 landed
-
bufmgr: Implement AIO read support
- 047cba7fa0f8 18.0 landed
-
aio: Add WARNING result status
- ef64fe26bad9 18.0 landed
-
Let caller of PageIsVerified() control ignore_checksum_failure
- d445990adc41 18.0 landed
-
pgstat: Allow checksum errors to be reported in critical sections
- b96d3c389755 18.0 landed
-
Add errhint_internal()
- 4244cf687697 18.0 landed
-
localbuf: Track pincount in BufferDesc as well
- d6d8054dc72d 18.0 landed
-
aio, bufmgr: Comment fixes/improvements
- 08ccd56ac765 18.0 landed
-
Fix mis-attribution of checksum failure stats to the wrong database
- dee80024688c 18.0 landed
-
aio: Implement support for reads in smgr/md/fd
- 50cb7505b301 18.0 landed
-
aio: Add io_method=io_uring
- c325a7633fcb 18.0 landed
-
aio: Add liburing dependency
- 8eadd5c73c44 18.0 landed
-
aio: Rename pgaio_io_prep_* to pgaio_io_start_*
- 9469d7fdd2bc 18.0 landed
-
aio: Pass result of local callbacks to ->report_return
- f321ec237a54 18.0 landed
-
aio: Be more paranoid about interrupts
- 96da9050a57a 18.0 landed
-
Redefine max_files_per_process to control additionally opened files
- adb5f85fa5a0 18.0 landed
-
aio: Change prefix of PgAioResultStatus values to PGAIO_RS_
- ca3067cc573d 18.0 landed
-
bufmgr: Improve stats when a buffer is read in concurrently
- 202b12774d09 18.0 landed
-
aio: Add io_method=worker
- 247ce06b883d 18.0 landed
-
aio: Infrastructure for io_method=worker
- 55b454d0e140 18.0 landed
-
aio: Add core asynchronous I/O infrastructure
- da7226993fd4 18.0 landed
-
aio: Basic subsystem initialization
- 02844012b304 18.0 landed
-
tests: Expand temp table tests to some pin related matters
- 1a22a8a0f131 18.0 landed
-
localbuf: Introduce FlushLocalBuffer()
- 4b4d33b9ea9f 18.0 landed
-
localbuf: Introduce TerminateLocalBufferIO()
- dd6f2618f681 18.0 landed
-
localbuf: Fix dangerous coding pattern in GetLocalVictimBuffer()
- fa6af9b25e4b 18.0 landed
-
localbuf: Introduce StartLocalBufferIO()
- 771ba90298e2 18.0 landed
-
localbuf: Introduce InvalidateLocalBuffer()
- 0762a151b0e0 18.0 landed
-
Allow lwlocks to be disowned
- f8d7f29b3e81 18.0 landed
-
Make jsonb casts to scalar types translate JSON null to SQL NULL.
- a5579a90af05 18.0 cited
-
bufmgr/smgr: Don't cross segment boundaries in StartReadBuffers()
- 755a4c10d19d 18.0 landed
-
Use aux process resource owner in walsender
- 57f370247127 18.0 landed
-
bufmgr: Return early in ScheduleBufferTagForWriteback() if fsync=off
- 488f826c729b 18.0 landed
On 7/14/25 20:36, Andres Freund wrote: > Hi, > > On 2025-07-11 23:03:53 +0200, Tomas Vondra wrote: >> I've been running some benchmarks comparing the io_methods, to help with >> resolving this PG18 open item. So here are some results, and my brief >> analysis of it. > > Thanks for doing that! > > > >> The TL;DR version >> ----------------- >> >> * The "worker" method seems good, and I think we should keep it as a >> default. We should probably think about increasing the number of workers >> a bit, the current io_workers=3 seems to be too low and regresses in a >> couple tests. >> >> * The "sync" seems OK too, but it's more of a conservative choice, i.e. >> more weight for keeping the PG17 behavior / not causing regressions. But >> I haven't seen that (with enough workers). And there are cases when the >> "worker" is much faster. It'd be a shame to throw away that benefit. >> >> * There might be bugs in "worker", simply because it has to deal with >> multiple concurrent processes etc. But I guess we'll fix those just like >> other bugs. I don't think it's a good argument against "worker" default. >> >> * All my tests were done on Linux and NVMe drives. It'd be good to do >> similar testing on other platforms (e.g. FreeBSD) and/or storage. I plan >> to do some of that, but it'd be great to cover more cases. I can help >> with getting my script running, a run takes ~1-2 days. > > FWIW, in my very limited tests on windows, the benefit of worker was > considerably bigger there, due to having much more minimal readahead not > having posix_fadvise... > > >> The test also included PG17 for comparison, but I forgot PG18 enabled >> checksums by default. So PG17 results are with checksums off, which in >> some cases means PG17 seems a little bit faster. I'm re-running it with >> checksums enabled on PG17, and that seems to eliminate the differences >> (as expected). > > My sneaking suspicion is that, independent of AIO, we're not really ready to > default to checksums defaulting to on. > > >> Findings >> -------- >> >> I'm attaching only three PDFs with charts from the cold runs, to keep >> the e-mail small (each PDF is ~100-200kB). Feel free to check the other >> PDFs in the git repository, but it's all very similar and the attached >> PDFs are quite representative. >> >> Some basic observations: >> >> a) index scans >> >> There's almost no difference for indexscans, i.e. the middle column in >> the PDFs. There's a bit of variation on some of the cyclic/linear data >> sets, but it seems more like random noise than a systemic difference. >> >> Which is not all that surprising, considering index scans don't really >> use read_stream yet, so there's no prefetching etc. > > Indeed. > > >> The "ryzen" results however demonstrate that 3 workers may be too low. >> The timing spikes to ~3000ms (at ~1% selectivity), before quickly >> dropping back to ~1000ms. The other datasets show similar difference. >> With 12 workers, there's no such problem. > > I don't really know what to do about that - for now we don't have dynamic > #workers, and starting 12 workers on a tiny database doesn't really make > sense... I suspect that on most hardware & queries it won't matter that much, > but clearly, if you have high iops hardware it might. I can perhaps see > increasing the default to 5 or so, but after that... I guess we could try > some autoconf formula based on the size of s_b or such? But that seems > somewhat awkward too. > True. I don't have a great idea either. FWIW most of our defaults are very conservative/low, and you have to bump them up on bigger machines anyway. So having to bump one more GUC is not a big deal, and I don't think we have to invent some magic formula for this one. Also, autoconf wouldn't even know about s_b size, it'd have to be something at startup. We could do some automated sizing if set to -1, perhaps. But is s_b even a good value to tie this to? I doubt that. > > >> >> e) indexscan regression (ryzen-indexscan-uniform-pg17-checksums.png) >> >> There's an interesting difference difference I noticed in the run with >> checksums on PG17. The full PDF is available here: > > (there's a subsequent email about this, will reply there) > > >> Conclusion >> ---------- >> >> That's all I have at the moment. I still think it makes sense to keep >> io_method=worker, but bump up the io_workers a bit higher. Could we also >> add some suggestions how to pick a good value to the docs? > > .oO(/me ponders a troll patch to re-add a reference the number of spindles in > that tuning advice) > ;-) > I'm not sure what advice to give here. Maybe just to set it to a considerably > larger number once not running on a tiny system? The incremental overhead of > having an idle worker is rather small unless you're on a really tiny system... > Too bad the patch doesn't collect any stats about how utilized the workers are :-( That'd make it a bit easier, we could even print something into the log if the queues overflow "too often", similarly to max_wal_size when checkpoints happen too often. > >> You might also run the benchmark on different hardware, and either >> build/publish the plots somewhere, or just give me the CSV and I'll do >> that. Better to find strange stuff / regressions now. > > Probably the most interesting thing would be some runs with cloud-ish storage > (relatively high iops, very high latency)... > Yeah, I've started a test on a cloud VM. Will see in a day or two. And another on FreeBSD, for good measure. > >> The repository also has branches with plots showing results with WIP >> indexscan prefetching. (It's excluded from the PDFs I presented here). > > Hm, I looked for those, but I couldn't quickly find any plots that include > them. Would I have to generate the plots from a checkout of the repo? > No, the charts are there, you don't need to generate them. Look into the "with-indexscan-prefetch-run2-17-checksums" branch. E.g. this is the same "ryzen" plot I shared earlier, but with "indexscan prefetch" column: https://github.com/tvondra/iomethod-tests/blob/with-indexscan-prefetch-run2-17-checksums/ryzen-rows-cold-32GB-16-unscaled.pdf It might be better to look at the "scaled" charts, which makes it easier to compare the different scans (and the benefit of prefetching). https://github.com/tvondra/iomethod-tests/blob/with-indexscan-prefetch-run2-17-checksums/ryzen-rows-cold-32GB-16-scaled.pdf > >> The conclusions are similar to what we found here - "worker" is good >> with enough workers, io_uring is good too. Sync has issues for some of >> the data sets, but still helps a lot. > > Nice. > > Greetings, > > Andres Freund regards -- Tomas Vondra