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:44, Andres Freund wrote: > On 2025-07-13 20:04:51 +0200, Tomas Vondra wrote: >> On 7/11/25 23:03, Tomas Vondra wrote: >>> ... >>> >>> 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: >>> >>> https://github.com/tvondra/iomethod-tests/blob/run2-17-checksums-on/ryzen-rows-cold-32GB-16-unscaled.pdf >>> >>> The interesting thing is that PG17 indexscans on uniform dataset got a >>> little bit faster. In the attached PDF it's exactly on par with PG18, >>> but here it got a bit faster. Which makes no sense, if it has to also >>> verify checksums. I haven't had time to investigate this yet. >> >> I was intrigued by this, so I looked into this today. >> >> TL;DR I believe it was caused by something in the filesystem or even the >> storage devices, making the "PG17" data directory (or maybe even just >> the "uniform" table) a bit faster. >> >> I started by reproducing the behavior with an indexscan matching 10% of >> the rows, and it was very easy to reproduce the difference shows on the >> chart (all timings in milliseconds): >> >> PG17: 14112.800 ms >> PG18: 21612.090 ms > > That's a decidedly nontrivial difference. > It is. It surprised me. > Did you keep any metrics from those runs? E.g. whether there were larger IOs > or such? > Unfortunately no. I should have investigated more before rebuilding the filesystem. But I suspect I might be able to reproduce it, if I do the loads in a loop or something like that. > >> This was perfectly reproducible, affecting the whole table (not just one >> part of it), etc. At some point I recalled that I might have initialized >> the databases in slightly different ways - one by running the SQL, the >> other one by pg_dump/pg_restore (likely with multiple jobs). > > I guess that's an INSERT ... SELECT vs COPY? > > Which one was the faster one? > I suspect I initialized one instance by the SQL script that generates data by INSERT ... SELECT for tables one by one (and then builds indexes, also one by one). And then I might have initialized the other database by pg_dump/pg_restore, so that'd be COPY. FWIW I might have used pg_restore with parallelism, and I suspect that might be more important than INSERT vs. COPY. But maybe I'm misremembering things, I rebuilt the benchmark databases so many times over the past couple days ... not sure. > If this ever re-occurs, it might be interesting to look at the fragmentation > of the underlying files with filefrag. > Yeah, I'll keep that in mind. And I'll try to reproduce this, once I'm done with those benchmarks. > >> I couldn't think of any other difference between the data directories, >> so I simply reloaded them by pg_restore (from the same dump). Which >> however made them both slow :O > > So that suggests that COPY is the slow case, interesting. > > One potentially relevant factor could be that parallel COPY into logged tables > currently leads to really sub-optimal write patterns, due to us writing back > buffers one-by-one, interspersed by WAL writes and file extensions. I know how > that affects write speed, but it's not entirely obvious how it would affect > read speed... > Maybe. I don't remember which database I loaded first. But this time I simply copied a backup of the data directory from a different device, which would "cleanup" the write pattern. I'd assume filesystems allocate space in larger chunks, e.g. ext4 does delayed allocation (and I don't see why that wouldn't work here). > >> And it didn't matter how many jobs are used, or anything else I tried. >> But every now and then an instance (17 or 18) happened to be fast >> (~14000 ms). Consistently, for all queries on the table, not randomly. >> >> In the end I recreated the (ext4) filesystem, loaded the databases and >> now both instances are fast. I have no idea what the root cause was, and >> I assume recreating the filesystem destroyed all the evidence. > > Besides differences in filesystem level fragmentation, another potential > theory is that the SSDs were internally more fragmented. Occasionally > dumping/restoring the data could allow the drive to do internal wear > leveling before the new data is loaded, leading to a better layout. > > I found that I get more consistent benchmark performance if I delete as much > of the data as possible, run fstrim -v -a and then load the data. And do > another round of fstrim. > Maybe, but the filesystem is far from full, which I think helps wear leveling. The RAID has ~4TB and only ~500GB was ever used. But who knows, and if that's the cause, we'll never really know I'm afraid. It's hard to confirm what happens inside a SSD :-( regards -- Tomas Vondra