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