@@ -973,12 +973,27 @@ lazy_scan_heap(LVRelState *vacrel)
973
973
*/
974
974
visibilitymap_pin (vacrel -> rel , blkno , & vmbuffer );
975
975
976
- if (enable_seqscan_prefetch )
976
+ if (enable_seqscan_prefetch && seqscan_prefetch_buffers > 0 )
977
977
{
978
- int prefetch_limit = Min (rel_pages - blkno - 1 , seqscan_prefetch_buffers );
979
- smgr_reset_prefetch (RelationGetSmgr (vacrel -> rel ));
980
- for (int i = 1 ; i <= prefetch_limit ; i ++ )
981
- PrefetchBuffer (vacrel -> rel , MAIN_FORKNUM , blkno + i );
978
+ /*
979
+ * If we're starting the scan, we need to prefetch the first N pages.
980
+ * If not, we need to only prefetch page blkno+n.
981
+ */
982
+ if (blkno == 0 )
983
+ {
984
+ int prefetch_limit = Min (rel_pages - blkno - 1 ,
985
+ seqscan_prefetch_buffers );
986
+
987
+ for (int i = 1 ; i <= prefetch_limit ; i ++ )
988
+ PrefetchBuffer (vacrel -> rel , MAIN_FORKNUM , blkno + i );
989
+ }
990
+ else
991
+ {
992
+ /* No need to prefetch past the end of the relation */
993
+ if (blkno + seqscan_prefetch_buffers < rel_pages )
994
+ PrefetchBuffer (vacrel -> rel , MAIN_FORKNUM ,
995
+ blkno + seqscan_prefetch_buffers );
996
+ }
982
997
}
983
998
984
999
/* Finished preparatory checks. Actually scan the page. */
@@ -2404,7 +2419,8 @@ lazy_vacuum_all_indexes(LVRelState *vacrel)
2404
2419
static void
2405
2420
lazy_vacuum_heap_rel (LVRelState * vacrel )
2406
2421
{
2407
- int index ;
2422
+ int index ,
2423
+ pindex ;
2408
2424
BlockNumber vacuumed_pages ;
2409
2425
Buffer vmbuffer = InvalidBuffer ;
2410
2426
LVSavedErrInfo saved_err_info ;
@@ -2425,6 +2441,7 @@ lazy_vacuum_heap_rel(LVRelState *vacrel)
2425
2441
vacuumed_pages = 0 ;
2426
2442
2427
2443
index = 0 ;
2444
+ pindex = 0 ;
2428
2445
while (index < vacrel -> dead_items -> num_items )
2429
2446
{
2430
2447
BlockNumber tblk ;
@@ -2435,13 +2452,44 @@ lazy_vacuum_heap_rel(LVRelState *vacrel)
2435
2452
vacuum_delay_point ();
2436
2453
2437
2454
tblk = ItemPointerGetBlockNumber (& vacrel -> dead_items -> items [index ]);
2438
- if (enable_seqscan_prefetch )
2455
+
2456
+ if (enable_seqscan_prefetch && seqscan_prefetch_buffers > 0 )
2439
2457
{
2440
- int prefetch_limit = Min (vacrel -> dead_items -> num_items - index - 1 , seqscan_prefetch_buffers );
2441
- smgr_reset_prefetch (RelationGetSmgr (vacrel -> rel ));
2442
- for (int i = 1 ; i <= prefetch_limit ; i ++ )
2443
- PrefetchBuffer (vacrel -> rel , MAIN_FORKNUM , ItemPointerGetBlockNumber (& vacrel -> dead_items -> items [index + i ]));
2458
+ /*
2459
+ * If we're just starting out, prefetch N consecutive blocks.
2460
+ * If not, only the next 1 block
2461
+ */
2462
+ if (index == 0 )
2463
+ {
2464
+ int prefetch_limit = Min (vacrel -> dead_items -> num_items - 1 ,
2465
+ Min (vacrel -> rel_pages ,
2466
+ seqscan_prefetch_buffers ));
2467
+ BlockNumber prev_prefetch = 0 ;
2468
+
2469
+ while (++ pindex < vacrel -> dead_items -> num_items &&
2470
+ prefetch_limit > 0 )
2471
+ {
2472
+ ItemPointer ptr = & vacrel -> dead_items -> items [pindex ];
2473
+ if (ItemPointerGetBlockNumber (ptr ) != prev_prefetch )
2474
+ {
2475
+ prev_prefetch = ItemPointerGetBlockNumber (ptr );
2476
+ prefetch_limit -= 1 ;
2477
+ PrefetchBuffer (vacrel -> rel , MAIN_FORKNUM , prev_prefetch );
2478
+ }
2479
+ }
2480
+ }
2481
+ else
2482
+ {
2483
+ BlockNumber toPrefetch = ItemPointerGetBlockNumber (& vacrel -> dead_items -> items [pindex ]);
2484
+ while (pindex < vacrel -> dead_items -> num_items )
2485
+ {
2486
+ if (toPrefetch != ItemPointerGetBlockNumber (& vacrel -> dead_items -> items [pindex ]))
2487
+ break ;
2488
+ }
2489
+ PrefetchBuffer (vacrel -> rel , MAIN_FORKNUM , toPrefetch );
2490
+ }
2444
2491
}
2492
+
2445
2493
vacrel -> blkno = tblk ;
2446
2494
buf = ReadBufferExtended (vacrel -> rel , MAIN_FORKNUM , tblk , RBM_NORMAL ,
2447
2495
vacrel -> bstrategy );
0 commit comments