From 7dda209d32625b9b237de0417f8ebc0783d8551c Mon Sep 17 00:00:00 2001 From: Thomas Munro Date: Tue, 21 Jan 2025 08:08:08 +1300 Subject: [PATCH v2.4 04/29] Allow more buffers for sequential read streams. Read streams currently only start concurrent I/Os (via read-ahead advice) for random access, with a hard-coded guesstimate that their average size is likely to be at most 4 blocks when planning the size of the buffer queue. Sequential streams benefit from kernel readahead when using buffered I/O, and read-ahead advice doesn't exist for direct I/O by definition, so we didn't need to look ahead more than io_combine_limit in that case. Proposed patches need more buffers to be able start multiple asynchronous I/O operations even for sequential access. Adjust the arithmetic in preparation, replacing "4" with io_combine_limit, though there is no benefit yet, just some wasted queue space. As of the time of writing, the maximum GUC values for effective_io_concurrent (1000) and io_combine_limit (32) imply a queue with around 32K entries (slightly more for technical reasons), though those numbers are likely to change. That requires a wider type in one place that has a intermediate value that might overflow before clamping. --- src/backend/storage/aio/read_stream.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backend/storage/aio/read_stream.c b/src/backend/storage/aio/read_stream.c index 1c93fcae19b..edeef292f75 100644 --- a/src/backend/storage/aio/read_stream.c +++ b/src/backend/storage/aio/read_stream.c @@ -499,7 +499,7 @@ read_stream_begin_impl(int flags, * overflow (even though that's not possible with the current GUC range * limits), allowing also for the spare entry and the overflow space. */ - max_pinned_buffers = Max(max_ios * 4, io_combine_limit); + max_pinned_buffers = Max(max_ios, 1) * io_combine_limit; max_pinned_buffers = Min(max_pinned_buffers, PG_INT16_MAX - io_combine_limit - 1); @@ -771,7 +771,7 @@ read_stream_next_buffer(ReadStream *stream, void **per_buffer_data) stream->ios[stream->oldest_io_index].buffer_index == oldest_buffer_index) { int16 io_index = stream->oldest_io_index; - int16 distance; + int32 distance; /* wider temporary value, clamped below */ /* Sanity check that we still agree on the buffers. */ Assert(stream->ios[io_index].op.buffers == -- 2.48.1.76.g4e746b1a31.dirty