Re: Streaming I/O, vectored I/O (WIP)

From: Heikki Linnakangas <hlinnaka(at)iki(dot)fi>
To: Thomas Munro <thomas(dot)munro(at)gmail(dot)com>, pgsql-hackers <pgsql-hackers(at)postgresql(dot)org>, Melanie Plageman <melanieplageman(at)gmail(dot)com>
Cc: Andres Freund <andres(at)anarazel(dot)de>
Subject: Re: Streaming I/O, vectored I/O (WIP)
Date: 2024-01-10 19:58:24
Message-ID: 7f034a1c-6d6f-406b-a082-c05aa269c184@iki.fi
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
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)

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Peter Eisentraut 2024-01-10 20:48:44 Re: Create shorthand for including all extra tests
Previous Message Tom Lane 2024-01-10 19:21:47 Re: Make psql ignore trailing semicolons in \sf, \ef, etc