Re: Streaming I/O, vectored I/O (WIP)
Heikki Linnakangas <hlinnaka@iki.fi>
From: Heikki Linnakangas <hlinnaka@iki.fi>
To: Thomas Munro <thomas.munro@gmail.com>,
pgsql-hackers <pgsql-hackers@postgresql.org>,
Melanie Plageman <melanieplageman@gmail.com>
Cc: Andres Freund <andres@anarazel.de>
Date: 2024-01-10T19:58:24Z
Lists: pgsql-hackers
On 10/01/2024 06:13, Thomas Munro wrote: > Bikeshedding call: I am open to better suggestions for the names > PrepareReadBuffer() and CompleteReadBuffers(), they seem a little > grammatically clumsy. How will these functions work in the brave new async I/O world? I assume PrepareReadBuffer() will initiate the async I/O, and CompleteReadBuffers() will wait for it to complete. How about StartReadBuffer() and WaitReadBuffer()? Or StartBufferRead() and WaitBufferRead()? About the signature of those functions: Does it make sense for CompleteReadBuffers() (or WaitReadBuffers()) function to take a vector of buffers? If StartReadBuffer() initiates the async I/O immediately, is there any benefit to batching the waiting? If StartReadBuffer() starts the async I/O, the idea that you can call ZeroBuffer() instead of WaitReadBuffer() doesn't work. I think StartReadBuffer() needs to take ReadBufferMode, and do the zeroing for you in RBM_ZERO_* modes. Putting all that together, I propose: /* * Initiate reading a block from disk to the buffer cache. * * XXX: Until we have async I/O, this just allocates the buffer in the buffer * cache. The actual I/O happens in WaitReadBuffer(). */ Buffer StartReadBuffer(BufferManagerRelation bmr, ForkNumber forkNum, BlockNumber blockNum, BufferAccessStrategy strategy, ReadBufferMode mode, bool *foundPtr); /* * Wait for a read that was started earlier with StartReadBuffer() to finish. * * XXX: Until we have async I/O, this is the function that actually performs * the I/O. If multiple I/Os have been started with StartReadBuffer(), this * will try to perform all of them in one syscall. Subsequent calls to * WaitReadBuffer(), for those other buffers, will finish quickly. */ void WaitReadBuffer(Buffer buf); I'm not sure how well this fits with the streaming read API. The streaming read code performs grouping of adjacent blocks to one CompleteReadBuffers() call. If WaitReadBuffer() does the batching, that's not really required. But does that make sense with async I/O? With async I/O, will you need a vectorized version of StartReadBuffer() too? -- Heikki Linnakangas Neon (https://neon.tech)
Commits
-
Fix typos and incorrect type in read_stream.c
- 2ea4b2927722 17.0 landed
-
Use streaming I/O in pg_prewarm.
- 3a352df05e65 17.0 landed
-
Provide API for streaming relation data.
- b5a9b18cd0bc 17.0 landed
-
Provide vectored variant of ReadBuffer().
- 210622c60e1a 17.0 landed
-
Provide vectored variants of smgrread() and smgrwrite().
- 4908c5872059 17.0 landed
-
Provide multi-block smgrprefetch().
- b485ad7f07c8 17.0 landed
-
Provide vectored variants of FileRead() and FileWrite().
- 871fe4917e1e 17.0 landed
-
Provide helper for retrying partial vectored I/O.
- 0c6be59f5e34 17.0 landed
-
Optimize pg_readv/pg_pwritev single vector case.
- 15c9ac362993 17.0 landed
-
bufmgr: Support multiple in-progress IOs by using resowner
- 12f3867f5534 16.0 cited