]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Use streaming read I/O in BRIN vacuum scan.
authorMasahiko Sawada <msawada@postgresql.org>
Mon, 17 Nov 2025 21:22:20 +0000 (13:22 -0800)
committerMasahiko Sawada <msawada@postgresql.org>
Mon, 17 Nov 2025 21:22:20 +0000 (13:22 -0800)
This commit implements streaming read I/O for BRIN vacuum
scans. Although BRIN indexes tend to be relatively small by design,
performance tests have shown performance improvements.

Author: Arseniy Mukhin <arseniy.mukhin.dev@gmail.com>
Discussion: https://postgr.es/m/CAE7r3ML01aiq9Th_1OSz7U7Aq2pWbhMLoz5T%2BPXcg8J9ZAPFFA%40mail.gmail.com

src/backend/access/brin/brin.c

index 2f7d1437919de27de50ee14bb2e64a838316f8c7..cb3331921cbfdae30e116be3f2bd676cf426d981 100644 (file)
@@ -2171,28 +2171,42 @@ union_tuples(BrinDesc *bdesc, BrinMemTuple *a, BrinTuple *b)
 static void
 brin_vacuum_scan(Relation idxrel, BufferAccessStrategy strategy)
 {
-       BlockNumber nblocks;
-       BlockNumber blkno;
+       BlockRangeReadStreamPrivate p;
+       ReadStream *stream;
+       Buffer          buf;
+
+       p.current_blocknum = 0;
+       p.last_exclusive = RelationGetNumberOfBlocks(idxrel);
+
+       /*
+        * It is safe to use batchmode as block_range_read_stream_cb takes no
+        * locks.
+        */
+       stream = read_stream_begin_relation(READ_STREAM_MAINTENANCE |
+                                                                               READ_STREAM_FULL |
+                                                                               READ_STREAM_USE_BATCHING,
+                                                                               strategy,
+                                                                               idxrel,
+                                                                               MAIN_FORKNUM,
+                                                                               block_range_read_stream_cb,
+                                                                               &p,
+                                                                               0);
 
        /*
         * Scan the index in physical order, and clean up any possible mess in
         * each page.
         */
-       nblocks = RelationGetNumberOfBlocks(idxrel);
-       for (blkno = 0; blkno < nblocks; blkno++)
+       while ((buf = read_stream_next_buffer(stream, NULL)) != InvalidBuffer)
        {
-               Buffer          buf;
-
                CHECK_FOR_INTERRUPTS();
 
-               buf = ReadBufferExtended(idxrel, MAIN_FORKNUM, blkno,
-                                                                RBM_NORMAL, strategy);
-
                brin_page_cleanup(idxrel, buf);
 
                ReleaseBuffer(buf);
        }
 
+       read_stream_end(stream);
+
        /*
         * Update all upper pages in the index's FSM, as well.  This ensures not
         * only that we propagate leaf-page FSM updates made by brin_page_cleanup,