@@ -217,7 +217,6 @@ typedef struct LVRelState
217217 */
218218typedef struct LVPagePruneState
219219{
220- bool hastup ;/* Page prevents rel truncation? */
221220bool has_lpdead_items ;/* includes existing LP_DEAD items */
222221
223222/*
@@ -253,7 +252,7 @@ static void lazy_scan_prune(LVRelState *vacrel, Buffer buf,
253252LVPagePruneState * prunestate );
254253static bool lazy_scan_noprune (LVRelState * vacrel ,Buffer buf ,
255254BlockNumber blkno ,Page page ,
256- bool * hastup , bool * recordfreespace );
255+ bool * recordfreespace );
257256static void lazy_vacuum (LVRelState * vacrel );
258257static bool lazy_vacuum_all_indexes (LVRelState * vacrel );
259258static void lazy_vacuum_heap_rel (LVRelState * vacrel );
@@ -959,8 +958,7 @@ lazy_scan_heap(LVRelState *vacrel)
959958page = BufferGetPage (buf );
960959if (!ConditionalLockBufferForCleanup (buf ))
961960{
962- bool hastup ,
963- recordfreespace ;
961+ bool recordfreespace ;
964962
965963LockBuffer (buf ,BUFFER_LOCK_SHARE );
966964
@@ -972,20 +970,21 @@ lazy_scan_heap(LVRelState *vacrel)
972970continue ;
973971}
974972
975- /* Collect LP_DEAD items in dead_items array, count tuples */
976- if (lazy_scan_noprune (vacrel ,buf ,blkno ,page ,& hastup ,
973+ /*
974+ * Collect LP_DEAD items in dead_items array, count tuples,
975+ * determine if rel truncation is safe
976+ */
977+ if (lazy_scan_noprune (vacrel ,buf ,blkno ,page ,
977978& recordfreespace ))
978979{
979980Size freespace = 0 ;
980981
981982/*
982983 * Processed page successfully (without cleanup lock) -- just
983- * need toperform rel truncation and FSM steps , much like the
984- *lazy_scan_prune case. Don't bother trying to match its
985- *visibility map setting steps, though.
984+ * need toupdate the FSM, much like the lazy_scan_prune case.
985+ * Don't bother trying to match its visibility map setting
986+ * steps, though.
986987 */
987- if (hastup )
988- vacrel -> nonempty_pages = blkno + 1 ;
989988if (recordfreespace )
990989freespace = PageGetHeapFreeSpace (page );
991990UnlockReleaseBuffer (buf );
@@ -1017,16 +1016,13 @@ lazy_scan_heap(LVRelState *vacrel)
10171016 * dead_items array. This includes LP_DEAD line pointers that we
10181017 * pruned ourselves, as well as existing LP_DEAD line pointers that
10191018 * were pruned some time earlier. Also considers freezing XIDs in the
1020- * tuple headers of remaining items with storage.
1019+ * tuple headers of remaining items with storage. It also determines
1020+ * if truncating this block is safe.
10211021 */
10221022lazy_scan_prune (vacrel ,buf ,blkno ,page ,& prunestate );
10231023
10241024Assert (!prunestate .all_visible || !prunestate .has_lpdead_items );
10251025
1026- /* Remember the location of the last page with nonremovable tuples */
1027- if (prunestate .hastup )
1028- vacrel -> nonempty_pages = blkno + 1 ;
1029-
10301026if (vacrel -> nindexes == 0 )
10311027{
10321028/*
@@ -1555,6 +1551,7 @@ lazy_scan_prune(LVRelState *vacrel,
15551551live_tuples ,
15561552recently_dead_tuples ;
15571553HeapPageFreeze pagefrz ;
1554+ bool hastup = false;
15581555int64 fpi_before = pgWalUsage .wal_fpi ;
15591556OffsetNumber deadoffsets [MaxHeapTuplesPerPage ];
15601557HeapTupleFreeze frozen [MaxHeapTuplesPerPage ];
@@ -1593,7 +1590,6 @@ lazy_scan_prune(LVRelState *vacrel,
15931590 * Now scan the page to collect LP_DEAD items and check for tuples
15941591 * requiring freezing among remaining tuples with storage
15951592 */
1596- prunestate -> hastup = false;
15971593prunestate -> has_lpdead_items = false;
15981594prunestate -> all_visible = true;
15991595prunestate -> all_frozen = true;
@@ -1620,7 +1616,7 @@ lazy_scan_prune(LVRelState *vacrel,
16201616if (ItemIdIsRedirected (itemid ))
16211617{
16221618/* page makes rel truncation unsafe */
1623- prunestate -> hastup = true;
1619+ hastup = true;
16241620continue ;
16251621}
16261622
@@ -1750,7 +1746,7 @@ lazy_scan_prune(LVRelState *vacrel,
17501746break ;
17511747}
17521748
1753- prunestate -> hastup = true;/* page makes rel truncation unsafe */
1749+ hastup = true;/* page makes rel truncation unsafe */
17541750
17551751/* Tuple with storage -- consider need to freeze */
17561752if (heap_prepare_freeze_tuple (htup ,& vacrel -> cutoffs ,& pagefrz ,
@@ -1918,6 +1914,10 @@ lazy_scan_prune(LVRelState *vacrel,
19181914vacrel -> lpdead_items += lpdead_items ;
19191915vacrel -> live_tuples += live_tuples ;
19201916vacrel -> recently_dead_tuples += recently_dead_tuples ;
1917+
1918+ /* Can't truncate this page */
1919+ if (hastup )
1920+ vacrel -> nonempty_pages = blkno + 1 ;
19211921}
19221922
19231923/*
@@ -1935,7 +1935,6 @@ lazy_scan_prune(LVRelState *vacrel,
19351935 * one or more tuples on the page. We always return true for non-aggressive
19361936 * callers.
19371937 *
1938- * See lazy_scan_prune for an explanation of hastup return flag.
19391938 * recordfreespace flag instructs caller on whether or not it should do
19401939 * generic FSM processing for page.
19411940 */
@@ -1944,7 +1943,6 @@ lazy_scan_noprune(LVRelState *vacrel,
19441943Buffer buf ,
19451944BlockNumber blkno ,
19461945Page page ,
1947- bool * hastup ,
19481946bool * recordfreespace )
19491947{
19501948OffsetNumber offnum ,
@@ -1953,14 +1951,15 @@ lazy_scan_noprune(LVRelState *vacrel,
19531951live_tuples ,
19541952recently_dead_tuples ,
19551953missed_dead_tuples ;
1954+ bool hastup ;
19561955HeapTupleHeader tupleheader ;
19571956TransactionId NoFreezePageRelfrozenXid = vacrel -> NewRelfrozenXid ;
19581957MultiXactId NoFreezePageRelminMxid = vacrel -> NewRelminMxid ;
19591958OffsetNumber deadoffsets [MaxHeapTuplesPerPage ];
19601959
19611960Assert (BufferGetBlockNumber (buf )== blkno );
19621961
1963- * hastup = false;/* for now */
1962+ hastup = false;/* for now */
19641963* recordfreespace = false;/* for now */
19651964
19661965lpdead_items = 0 ;
@@ -1984,7 +1983,7 @@ lazy_scan_noprune(LVRelState *vacrel,
19841983
19851984if (ItemIdIsRedirected (itemid ))
19861985{
1987- * hastup = true;
1986+ hastup = true;
19881987continue ;
19891988}
19901989
@@ -1998,7 +1997,7 @@ lazy_scan_noprune(LVRelState *vacrel,
19981997continue ;
19991998}
20001999
2001- * hastup = true;/* page prevents rel truncation */
2000+ hastup = true;/* page prevents rel truncation */
20022001tupleheader = (HeapTupleHeader )PageGetItem (page ,itemid );
20032002if (heap_tuple_should_freeze (tupleheader ,& vacrel -> cutoffs ,
20042003& NoFreezePageRelfrozenXid ,
@@ -2100,7 +2099,7 @@ lazy_scan_noprune(LVRelState *vacrel,
21002099 * but it beats having to maintain specialized heap vacuuming code
21012100 * forever, for vanishingly little benefit.)
21022101 */
2103- * hastup = true;
2102+ hastup = true;
21042103missed_dead_tuples += lpdead_items ;
21052104}
21062105
@@ -2156,6 +2155,10 @@ lazy_scan_noprune(LVRelState *vacrel,
21562155if (missed_dead_tuples > 0 )
21572156vacrel -> missed_dead_pages ++ ;
21582157
2158+ /* Can't truncate this page */
2159+ if (hastup )
2160+ vacrel -> nonempty_pages = blkno + 1 ;
2161+
21592162/* Caller won't need to call lazy_scan_prune with same page */
21602163return true;
21612164}