Use scanned_pages to decide when to failsafe check.
authorPeter Geoghegan <[email protected]>
Thu, 22 Dec 2022 18:41:40 +0000 (10:41 -0800)
committerPeter Geoghegan <[email protected]>
Thu, 22 Dec 2022 18:41:40 +0000 (10:41 -0800)
Perform a failsafe check every time VACUUM's first heap scan scans a
further FAILSAFE_EVERY_PAGES pages, rather than using an approach based
on the number of physical blocks that our current blkno is from the
blkno at the time of the previous failsafe check.  That way VACUUM will
perform a failsafe check every time it has scanned a uniform number of
pages, without it mattering when or how VACUUM skipped pages using the
visibility map.

Sami Imseih, with changes to FAILSAFE_EVERY_PAGES comments added by me.

Author: Sami Imseih <[email protected]>
Reviewed-By: Peter Geoghegan <[email protected]>
Discussion: https://postgr.es/m/401CE010-4049-4B94-9961-0B610A5D254D%40amazon.com

src/backend/access/heap/vacuumlazy.c

index e40150379513c39e478a0b7dd3e4c1566c9855b1..98ccb98825bc320e33dd1972070c14e9c778f445 100644 (file)
@@ -94,7 +94,8 @@
 #define BYPASS_THRESHOLD_PAGES 0.02    /* i.e. 2% of rel_pages */
 
 /*
- * Perform a failsafe check every 4GB during the heap scan, approximately
+ * Perform a failsafe check each time we scan another 4GB of pages.
+ * (Note that this is deliberately kept to a power-of-two, usually 2^19.)
  */
 #define FAILSAFE_EVERY_PAGES \
        ((BlockNumber) (((uint64) 4 * 1024 * 1024 * 1024) / BLCKSZ))
@@ -821,7 +822,6 @@ lazy_scan_heap(LVRelState *vacrel)
        BlockNumber rel_pages = vacrel->rel_pages,
                                blkno,
                                next_unskippable_block,
-                               next_failsafe_block = 0,
                                next_fsm_block_to_vacuum = 0;
        VacDeadItems *dead_items = vacrel->dead_items;
        Buffer          vmbuffer = InvalidBuffer;
@@ -895,11 +895,8 @@ lazy_scan_heap(LVRelState *vacrel)
                 * one-pass strategy, and the two-pass strategy with the index_cleanup
                 * param set to 'off'.
                 */
-               if (blkno - next_failsafe_block >= FAILSAFE_EVERY_PAGES)
-               {
+               if (vacrel->scanned_pages % FAILSAFE_EVERY_PAGES == 0)
                        lazy_check_wraparound_failsafe(vacrel);
-                       next_failsafe_block = blkno;
-               }
 
                /*
                 * Consider if we definitely have enough space to process TIDs on page