@@ -217,7 +217,6 @@ typedef struct LVRelState
217
217
*/
218
218
typedef struct LVPagePruneState
219
219
{
220
- bool hastup ; /* Page prevents rel truncation? */
221
220
bool has_lpdead_items ; /* includes existing LP_DEAD items */
222
221
223
222
/*
@@ -253,7 +252,7 @@ static void lazy_scan_prune(LVRelState *vacrel, Buffer buf,
253
252
LVPagePruneState * prunestate );
254
253
static bool lazy_scan_noprune (LVRelState * vacrel , Buffer buf ,
255
254
BlockNumber blkno , Page page ,
256
- bool * hastup , bool * recordfreespace );
255
+ bool * recordfreespace );
257
256
static void lazy_vacuum (LVRelState * vacrel );
258
257
static bool lazy_vacuum_all_indexes (LVRelState * vacrel );
259
258
static void lazy_vacuum_heap_rel (LVRelState * vacrel );
@@ -959,8 +958,7 @@ lazy_scan_heap(LVRelState *vacrel)
959
958
page = BufferGetPage (buf );
960
959
if (!ConditionalLockBufferForCleanup (buf ))
961
960
{
962
- bool hastup ,
963
- recordfreespace ;
961
+ bool recordfreespace ;
964
962
965
963
LockBuffer (buf , BUFFER_LOCK_SHARE );
966
964
@@ -972,20 +970,21 @@ lazy_scan_heap(LVRelState *vacrel)
972
970
continue ;
973
971
}
974
972
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 ,
977
978
& recordfreespace ))
978
979
{
979
980
Size freespace = 0 ;
980
981
981
982
/*
982
983
* Processed page successfully (without cleanup lock) -- just
983
- * need to perform 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 to update the FSM, much like the lazy_scan_prune case.
985
+ * Don't bother trying to match its visibility map setting
986
+ * steps, though.
986
987
*/
987
- if (hastup )
988
- vacrel -> nonempty_pages = blkno + 1 ;
989
988
if (recordfreespace )
990
989
freespace = PageGetHeapFreeSpace (page );
991
990
UnlockReleaseBuffer (buf );
@@ -1017,16 +1016,13 @@ lazy_scan_heap(LVRelState *vacrel)
1017
1016
* dead_items array. This includes LP_DEAD line pointers that we
1018
1017
* pruned ourselves, as well as existing LP_DEAD line pointers that
1019
1018
* 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.
1021
1021
*/
1022
1022
lazy_scan_prune (vacrel , buf , blkno , page , & prunestate );
1023
1023
1024
1024
Assert (!prunestate .all_visible || !prunestate .has_lpdead_items );
1025
1025
1026
- /* Remember the location of the last page with nonremovable tuples */
1027
- if (prunestate .hastup )
1028
- vacrel -> nonempty_pages = blkno + 1 ;
1029
-
1030
1026
if (vacrel -> nindexes == 0 )
1031
1027
{
1032
1028
/*
@@ -1555,6 +1551,7 @@ lazy_scan_prune(LVRelState *vacrel,
1555
1551
live_tuples ,
1556
1552
recently_dead_tuples ;
1557
1553
HeapPageFreeze pagefrz ;
1554
+ bool hastup = false;
1558
1555
int64 fpi_before = pgWalUsage .wal_fpi ;
1559
1556
OffsetNumber deadoffsets [MaxHeapTuplesPerPage ];
1560
1557
HeapTupleFreeze frozen [MaxHeapTuplesPerPage ];
@@ -1593,7 +1590,6 @@ lazy_scan_prune(LVRelState *vacrel,
1593
1590
* Now scan the page to collect LP_DEAD items and check for tuples
1594
1591
* requiring freezing among remaining tuples with storage
1595
1592
*/
1596
- prunestate -> hastup = false;
1597
1593
prunestate -> has_lpdead_items = false;
1598
1594
prunestate -> all_visible = true;
1599
1595
prunestate -> all_frozen = true;
@@ -1620,7 +1616,7 @@ lazy_scan_prune(LVRelState *vacrel,
1620
1616
if (ItemIdIsRedirected (itemid ))
1621
1617
{
1622
1618
/* page makes rel truncation unsafe */
1623
- prunestate -> hastup = true;
1619
+ hastup = true;
1624
1620
continue ;
1625
1621
}
1626
1622
@@ -1750,7 +1746,7 @@ lazy_scan_prune(LVRelState *vacrel,
1750
1746
break ;
1751
1747
}
1752
1748
1753
- prunestate -> hastup = true; /* page makes rel truncation unsafe */
1749
+ hastup = true; /* page makes rel truncation unsafe */
1754
1750
1755
1751
/* Tuple with storage -- consider need to freeze */
1756
1752
if (heap_prepare_freeze_tuple (htup , & vacrel -> cutoffs , & pagefrz ,
@@ -1918,6 +1914,10 @@ lazy_scan_prune(LVRelState *vacrel,
1918
1914
vacrel -> lpdead_items += lpdead_items ;
1919
1915
vacrel -> live_tuples += live_tuples ;
1920
1916
vacrel -> recently_dead_tuples += recently_dead_tuples ;
1917
+
1918
+ /* Can't truncate this page */
1919
+ if (hastup )
1920
+ vacrel -> nonempty_pages = blkno + 1 ;
1921
1921
}
1922
1922
1923
1923
/*
@@ -1935,7 +1935,6 @@ lazy_scan_prune(LVRelState *vacrel,
1935
1935
* one or more tuples on the page. We always return true for non-aggressive
1936
1936
* callers.
1937
1937
*
1938
- * See lazy_scan_prune for an explanation of hastup return flag.
1939
1938
* recordfreespace flag instructs caller on whether or not it should do
1940
1939
* generic FSM processing for page.
1941
1940
*/
@@ -1944,7 +1943,6 @@ lazy_scan_noprune(LVRelState *vacrel,
1944
1943
Buffer buf ,
1945
1944
BlockNumber blkno ,
1946
1945
Page page ,
1947
- bool * hastup ,
1948
1946
bool * recordfreespace )
1949
1947
{
1950
1948
OffsetNumber offnum ,
@@ -1953,14 +1951,15 @@ lazy_scan_noprune(LVRelState *vacrel,
1953
1951
live_tuples ,
1954
1952
recently_dead_tuples ,
1955
1953
missed_dead_tuples ;
1954
+ bool hastup ;
1956
1955
HeapTupleHeader tupleheader ;
1957
1956
TransactionId NoFreezePageRelfrozenXid = vacrel -> NewRelfrozenXid ;
1958
1957
MultiXactId NoFreezePageRelminMxid = vacrel -> NewRelminMxid ;
1959
1958
OffsetNumber deadoffsets [MaxHeapTuplesPerPage ];
1960
1959
1961
1960
Assert (BufferGetBlockNumber (buf ) == blkno );
1962
1961
1963
- * hastup = false; /* for now */
1962
+ hastup = false; /* for now */
1964
1963
* recordfreespace = false; /* for now */
1965
1964
1966
1965
lpdead_items = 0 ;
@@ -1984,7 +1983,7 @@ lazy_scan_noprune(LVRelState *vacrel,
1984
1983
1985
1984
if (ItemIdIsRedirected (itemid ))
1986
1985
{
1987
- * hastup = true;
1986
+ hastup = true;
1988
1987
continue ;
1989
1988
}
1990
1989
@@ -1998,7 +1997,7 @@ lazy_scan_noprune(LVRelState *vacrel,
1998
1997
continue ;
1999
1998
}
2000
1999
2001
- * hastup = true; /* page prevents rel truncation */
2000
+ hastup = true; /* page prevents rel truncation */
2002
2001
tupleheader = (HeapTupleHeader ) PageGetItem (page , itemid );
2003
2002
if (heap_tuple_should_freeze (tupleheader , & vacrel -> cutoffs ,
2004
2003
& NoFreezePageRelfrozenXid ,
@@ -2100,7 +2099,7 @@ lazy_scan_noprune(LVRelState *vacrel,
2100
2099
* but it beats having to maintain specialized heap vacuuming code
2101
2100
* forever, for vanishingly little benefit.)
2102
2101
*/
2103
- * hastup = true;
2102
+ hastup = true;
2104
2103
missed_dead_tuples += lpdead_items ;
2105
2104
}
2106
2105
@@ -2156,6 +2155,10 @@ lazy_scan_noprune(LVRelState *vacrel,
2156
2155
if (missed_dead_tuples > 0 )
2157
2156
vacrel -> missed_dead_pages ++ ;
2158
2157
2158
+ /* Can't truncate this page */
2159
+ if (hastup )
2160
+ vacrel -> nonempty_pages = blkno + 1 ;
2161
+
2159
2162
/* Caller won't need to call lazy_scan_prune with same page */
2160
2163
return true;
2161
2164
}
0 commit comments