1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-27 12:41:57 +03:00

read_stream: Introduce and use optional batchmode support

Submitting IO in larger batches can be more efficient than doing so
one-by-one, particularly for many small reads. It does, however, require
the ReadStreamBlockNumberCB callback to abide by the restrictions of AIO
batching (c.f. pgaio_enter_batchmode()). Basically, the callback may not:
a) block without first calling pgaio_submit_staged(), unless a
   to-be-waited-on lock cannot be part of a deadlock, e.g. because it is
   never held while waiting for IO.

b) directly or indirectly start another batch pgaio_enter_batchmode()

As this requires care and is nontrivial in some cases, batching is only
used with explicit opt-in.

This patch adds an explicit flag (READ_STREAM_USE_BATCHING) to read_stream and
uses it where appropriate.

There are two cases where batching would likely be beneficial, but where we
aren't using it yet:

1) bitmap heap scans, because the callback reads the VM

   This should soon be solved, because we are planning to remove the use of
   the VM, due to that not being sound.

2) The first phase of heap vacuum

   This could be made to support batchmode, but would require some care.

Reviewed-by: Noah Misch <noah@leadboat.com>
Reviewed-by: Thomas Munro <thomas.munro@gmail.com>
Discussion: https://postgr.es/m/uvrtrknj4kdytuboidbhwclo4gxhswwcpgadptsjvjqcluzmah%40brqs62irg4dt
This commit is contained in:
Andres Freund
2025-03-30 18:30:36 -04:00
parent f4d0730bbc
commit ae3df4b341
12 changed files with 129 additions and 12 deletions

View File

@ -447,12 +447,23 @@ verify_heapam(PG_FUNCTION_ARGS)
if (skip_option == SKIP_PAGES_NONE)
{
/*
* It is safe to use batchmode as block_range_read_stream_cb takes no
* locks.
*/
stream_cb = block_range_read_stream_cb;
stream_flags = READ_STREAM_SEQUENTIAL | READ_STREAM_FULL;
stream_flags = READ_STREAM_SEQUENTIAL |
READ_STREAM_FULL |
READ_STREAM_USE_BATCHING;
stream_data = &stream_skip_data.range;
}
else
{
/*
* It would not be safe to naively use use batchmode, as
* heapcheck_read_stream_next_unskippable takes locks. It shouldn't be
* too hard to convert though.
*/
stream_cb = heapcheck_read_stream_next_unskippable;
stream_flags = READ_STREAM_DEFAULT;
stream_data = &stream_skip_data;

View File

@ -198,7 +198,12 @@ pg_prewarm(PG_FUNCTION_ARGS)
p.current_blocknum = first_block;
p.last_exclusive = last_block + 1;
stream = read_stream_begin_relation(READ_STREAM_FULL,
/*
* It is safe to use batchmode as block_range_read_stream_cb takes no
* locks.
*/
stream = read_stream_begin_relation(READ_STREAM_FULL |
READ_STREAM_USE_BATCHING,
NULL,
rel,
forkNumber,

View File

@ -526,7 +526,13 @@ collect_visibility_data(Oid relid, bool include_pd)
{
p.current_blocknum = 0;
p.last_exclusive = nblocks;
stream = read_stream_begin_relation(READ_STREAM_FULL,
/*
* It is safe to use batchmode as block_range_read_stream_cb takes no
* locks.
*/
stream = read_stream_begin_relation(READ_STREAM_FULL |
READ_STREAM_USE_BATCHING,
bstrategy,
rel,
MAIN_FORKNUM,