From c4d7478b9e95f669857815a6be33e061aff82e5b Mon Sep 17 00:00:00 2001 From: Jingtang Zhang Date: Wed, 9 Sep 2026 20:28:29 +0800 Subject: [PATCH v3] Use maintenance I/O concurrency for index builds Heap scans for index builds currently use ordinary query I/O concurrency. Mark serial and parallel index build scans as maintenance work so their read streams use the maintenance setting, including tablespace overrides. BRIN range summarization shares the serial scan path and is covered too. Preserve the existing scan options and interfaces. The separate heap validation scan during concurrent index creation is unchanged. --- src/backend/access/brin/brin.c | 2 +- src/backend/access/gin/gininsert.c | 2 +- src/backend/access/heap/heapam.c | 7 +++++-- src/backend/access/heap/heapam_handler.c | 19 +++++++++++++------ src/backend/access/nbtree/nbtsort.c | 2 +- src/include/access/tableam.h | 3 +++ 6 files changed, 24 insertions(+), 11 deletions(-) diff --git a/src/backend/access/brin/brin.c b/src/backend/access/brin/brin.c index 5059da8dce7..b6f3f87d768 100644 --- a/src/backend/access/brin/brin.c +++ b/src/backend/access/brin/brin.c @@ -2845,7 +2845,7 @@ _brin_parallel_scan_and_build(BrinBuildState *state, scan = table_beginscan_parallel(heap, ParallelTableScanFromBrinShared(brinshared), - SO_NONE); + SO_MAINTENANCE); reltuples = table_index_build_scan(heap, index, indexInfo, true, true, brinbuildCallbackParallel, state, scan); diff --git a/src/backend/access/gin/gininsert.c b/src/backend/access/gin/gininsert.c index 37f689a2cac..07b5ca82167 100644 --- a/src/backend/access/gin/gininsert.c +++ b/src/backend/access/gin/gininsert.c @@ -2066,7 +2066,7 @@ _gin_parallel_scan_and_build(GinBuildState *state, scan = table_beginscan_parallel(heap, ParallelTableScanFromGinBuildShared(ginshared), - SO_NONE); + SO_MAINTENANCE); reltuples = table_index_build_scan(heap, index, indexInfo, true, progress, ginBuildCallbackParallel, state, scan); diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index 72d6541734c..1bb5d6afa64 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -1281,6 +1281,10 @@ heap_beginscan(Relation relation, Snapshot snapshot, scan->rs_base.rs_flags & SO_TYPE_TIDRANGESCAN) { ReadStreamBlockNumberCB cb; + int stream_flags = READ_STREAM_SEQUENTIAL | READ_STREAM_USE_BATCHING; + + if (scan->rs_base.rs_flags & SO_MAINTENANCE) + stream_flags |= READ_STREAM_MAINTENANCE; if (scan->rs_base.rs_parallel) cb = heap_scan_stream_read_next_parallel; @@ -1294,8 +1298,7 @@ heap_beginscan(Relation relation, Snapshot snapshot, * - in the parallel case, only spinlocks and atomics are used * --- */ - scan->rs_read_stream = read_stream_begin_relation(READ_STREAM_SEQUENTIAL | - READ_STREAM_USE_BATCHING, + scan->rs_read_stream = read_stream_begin_relation(stream_flags, scan->rs_strategy, scan->rs_base.rs_rd, MAIN_FORKNUM, diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index 0f24a132564..9c3536eaa1b 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -1211,6 +1211,9 @@ heapam_index_build_range_scan(Relation heapRelation, if (!scan) { + uint32 internal_flags = SO_TYPE_SEQSCAN | + SO_ALLOW_PAGEMODE | SO_ALLOW_STRAT; + /* * Serial index build. * @@ -1225,12 +1228,16 @@ heapam_index_build_range_scan(Relation heapRelation, else snapshot = SnapshotAny; - scan = table_beginscan_strat(heapRelation, /* relation */ - snapshot, /* snapshot */ - 0, /* number of keys */ - NULL, /* scan key */ - true, /* buffer access strategy OK */ - allow_sync); /* syncscan OK? */ + if (allow_sync) + internal_flags |= SO_ALLOW_SYNC; + + scan = table_beginscan_common(heapRelation, /* relation */ + snapshot, /* snapshot */ + 0, /* number of keys */ + NULL, /* scan key */ + NULL, /* serial scan */ + internal_flags, + SO_MAINTENANCE); } else { diff --git a/src/backend/access/nbtree/nbtsort.c b/src/backend/access/nbtree/nbtsort.c index 756dfa3dcf4..ff5ed01718c 100644 --- a/src/backend/access/nbtree/nbtsort.c +++ b/src/backend/access/nbtree/nbtsort.c @@ -1929,7 +1929,7 @@ _bt_parallel_scan_and_sort(BTSpool *btspool, BTSpool *btspool2, indexInfo->ii_Concurrent = btshared->isconcurrent; scan = table_beginscan_parallel(btspool->heap, ParallelTableScanFromBTShared(btshared), - SO_NONE); + SO_MAINTENANCE); reltuples = table_index_build_scan(btspool->heap, btspool->index, indexInfo, true, progress, _bt_build_callback, &buildstate, scan); diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ff03a2b816f..31f49814433 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -72,6 +72,9 @@ typedef enum ScanOptions /* collect scan instrumentation */ SO_SCAN_INSTRUMENT = 1 << 11, + + /* use maintenance I/O concurrency */ + SO_MAINTENANCE = 1 << 12, } ScanOptions; /* -- 2.43.7