Remove hastup from LVPagePruneState.
authorRobert Haas <rhaas@postgresql.org>
Thu, 11 Jan 2024 18:22:04 +0000 (13:22 -0500)
committerRobert Haas <rhaas@postgresql.org>
Thu, 11 Jan 2024 18:30:12 +0000 (13:30 -0500)
Instead, just have lazy_scan_prune() and lazy_scan_noprune() update
LVRelState->nonempty_pages directly. This makes the two functions
more similar and also removes makes lazy_scan_noprune need one fewer
output parameters.

Melanie Plageman, reviewed by Andres Freund, Michael Paquier, and me

Discussion: http://postgr.es/m/CAAKRu_btji_wQdg=ok-5E4v_bGVxKYnnFFe7RA6Frc1EcOwtSg@mail.gmail.com

src/backend/access/heap/vacuumlazy.c

index abbba8947faded31e3275720157757a25570813f..b63cad1335f1944c8aac2dc0366038721599d59f 100644 (file)
@@ -217,7 +217,6 @@ typedef struct LVRelState
  */
 typedef struct LVPagePruneState
 {
-       bool            hastup;                 /* Page prevents rel truncation? */
        bool            has_lpdead_items;       /* includes existing LP_DEAD items */
 
        /*
@@ -253,7 +252,7 @@ static void lazy_scan_prune(LVRelState *vacrel, Buffer buf,
                                                        LVPagePruneState *prunestate);
 static bool lazy_scan_noprune(LVRelState *vacrel, Buffer buf,
                                                          BlockNumber blkno, Page page,
-                                                         bool *hastup, bool *recordfreespace);
+                                                         bool *recordfreespace);
 static void lazy_vacuum(LVRelState *vacrel);
 static bool lazy_vacuum_all_indexes(LVRelState *vacrel);
 static void lazy_vacuum_heap_rel(LVRelState *vacrel);
@@ -959,8 +958,7 @@ lazy_scan_heap(LVRelState *vacrel)
                page = BufferGetPage(buf);
                if (!ConditionalLockBufferForCleanup(buf))
                {
-                       bool            hastup,
-                                               recordfreespace;
+                       bool            recordfreespace;
 
                        LockBuffer(buf, BUFFER_LOCK_SHARE);
 
@@ -972,20 +970,21 @@ lazy_scan_heap(LVRelState *vacrel)
                                continue;
                        }
 
-                       /* Collect LP_DEAD items in dead_items array, count tuples */
-                       if (lazy_scan_noprune(vacrel, buf, blkno, page, &hastup,
+                       /*
+                        * Collect LP_DEAD items in dead_items array, count tuples,
+                        * determine if rel truncation is safe
+                        */
+                       if (lazy_scan_noprune(vacrel, buf, blkno, page,
                                                                  &recordfreespace))
                        {
                                Size            freespace = 0;
 
                                /*
                                 * Processed page successfully (without cleanup lock) -- just
-                                * need to perform rel truncation and FSM steps, much like the
-                                * lazy_scan_prune case.  Don't bother trying to match its
-                                * visibility map setting steps, though.
+                                * need to update the FSM, much like the lazy_scan_prune case.
+                                * Don't bother trying to match its visibility map setting
+                                * steps, though.
                                 */
-                               if (hastup)
-                                       vacrel->nonempty_pages = blkno + 1;
                                if (recordfreespace)
                                        freespace = PageGetHeapFreeSpace(page);
                                UnlockReleaseBuffer(buf);
@@ -1017,16 +1016,13 @@ lazy_scan_heap(LVRelState *vacrel)
                 * dead_items array.  This includes LP_DEAD line pointers that we
                 * pruned ourselves, as well as existing LP_DEAD line pointers that
                 * were pruned some time earlier.  Also considers freezing XIDs in the
-                * tuple headers of remaining items with storage.
+                * tuple headers of remaining items with storage. It also determines
+                * if truncating this block is safe.
                 */
                lazy_scan_prune(vacrel, buf, blkno, page, &prunestate);
 
                Assert(!prunestate.all_visible || !prunestate.has_lpdead_items);
 
-               /* Remember the location of the last page with nonremovable tuples */
-               if (prunestate.hastup)
-                       vacrel->nonempty_pages = blkno + 1;
-
                if (vacrel->nindexes == 0)
                {
                        /*
@@ -1555,6 +1551,7 @@ lazy_scan_prune(LVRelState *vacrel,
                                live_tuples,
                                recently_dead_tuples;
        HeapPageFreeze pagefrz;
+       bool            hastup = false;
        int64           fpi_before = pgWalUsage.wal_fpi;
        OffsetNumber deadoffsets[MaxHeapTuplesPerPage];
        HeapTupleFreeze frozen[MaxHeapTuplesPerPage];
@@ -1593,7 +1590,6 @@ lazy_scan_prune(LVRelState *vacrel,
         * Now scan the page to collect LP_DEAD items and check for tuples
         * requiring freezing among remaining tuples with storage
         */
-       prunestate->hastup = false;
        prunestate->has_lpdead_items = false;
        prunestate->all_visible = true;
        prunestate->all_frozen = true;
@@ -1620,7 +1616,7 @@ lazy_scan_prune(LVRelState *vacrel,
                if (ItemIdIsRedirected(itemid))
                {
                        /* page makes rel truncation unsafe */
-                       prunestate->hastup = true;
+                       hastup = true;
                        continue;
                }
 
@@ -1750,7 +1746,7 @@ lazy_scan_prune(LVRelState *vacrel,
                                break;
                }
 
-               prunestate->hastup = true;      /* page makes rel truncation unsafe */
+               hastup = true;                  /* page makes rel truncation unsafe */
 
                /* Tuple with storage -- consider need to freeze */
                if (heap_prepare_freeze_tuple(htup, &vacrel->cutoffs, &pagefrz,
@@ -1918,6 +1914,10 @@ lazy_scan_prune(LVRelState *vacrel,
        vacrel->lpdead_items += lpdead_items;
        vacrel->live_tuples += live_tuples;
        vacrel->recently_dead_tuples += recently_dead_tuples;
+
+       /* Can't truncate this page */
+       if (hastup)
+               vacrel->nonempty_pages = blkno + 1;
 }
 
 /*
@@ -1935,7 +1935,6 @@ lazy_scan_prune(LVRelState *vacrel,
  * one or more tuples on the page.  We always return true for non-aggressive
  * callers.
  *
- * See lazy_scan_prune for an explanation of hastup return flag.
  * recordfreespace flag instructs caller on whether or not it should do
  * generic FSM processing for page.
  */
@@ -1944,7 +1943,6 @@ lazy_scan_noprune(LVRelState *vacrel,
                                  Buffer buf,
                                  BlockNumber blkno,
                                  Page page,
-                                 bool *hastup,
                                  bool *recordfreespace)
 {
        OffsetNumber offnum,
@@ -1953,6 +1951,7 @@ lazy_scan_noprune(LVRelState *vacrel,
                                live_tuples,
                                recently_dead_tuples,
                                missed_dead_tuples;
+       bool            hastup;
        HeapTupleHeader tupleheader;
        TransactionId NoFreezePageRelfrozenXid = vacrel->NewRelfrozenXid;
        MultiXactId NoFreezePageRelminMxid = vacrel->NewRelminMxid;
@@ -1960,7 +1959,7 @@ lazy_scan_noprune(LVRelState *vacrel,
 
        Assert(BufferGetBlockNumber(buf) == blkno);
 
-       *hastup = false;                        /* for now */
+       hastup = false;                         /* for now */
        *recordfreespace = false;       /* for now */
 
        lpdead_items = 0;
@@ -1984,7 +1983,7 @@ lazy_scan_noprune(LVRelState *vacrel,
 
                if (ItemIdIsRedirected(itemid))
                {
-                       *hastup = true;
+                       hastup = true;
                        continue;
                }
 
@@ -1998,7 +1997,7 @@ lazy_scan_noprune(LVRelState *vacrel,
                        continue;
                }
 
-               *hastup = true;                 /* page prevents rel truncation */
+               hastup = true;                  /* page prevents rel truncation */
                tupleheader = (HeapTupleHeader) PageGetItem(page, itemid);
                if (heap_tuple_should_freeze(tupleheader, &vacrel->cutoffs,
                                                                         &NoFreezePageRelfrozenXid,
@@ -2100,7 +2099,7 @@ lazy_scan_noprune(LVRelState *vacrel,
                         * but it beats having to maintain specialized heap vacuuming code
                         * forever, for vanishingly little benefit.)
                         */
-                       *hastup = true;
+                       hastup = true;
                        missed_dead_tuples += lpdead_items;
                }
 
@@ -2156,6 +2155,10 @@ lazy_scan_noprune(LVRelState *vacrel,
        if (missed_dead_tuples > 0)
                vacrel->missed_dead_pages++;
 
+       /* Can't truncate this page */
+       if (hastup)
+               vacrel->nonempty_pages = blkno + 1;
+
        /* Caller won't need to call lazy_scan_prune with same page */
        return true;
 }