agora inbox for [email protected]
help / color / mirror / Atom feedFrom: Melanie Plageman <[email protected]>
Subject: [PATCH v10 08/10] Set hastup in heap_page_prune
Date: Fri, 29 Mar 2024 21:36:37 -0400
lazy_scan_prune() loops through the line pointers and tuple visibility
information for each tuple on a page, setting hastup to true if there
are any LP_REDIRECT line pointers or tuples with storage which will not
be removed. We want to remove this extra loop from lazy_scan_prune(),
and we know about non-removable tuples during heap_page_prune() anyway.
Set hastup when recording LP_REDIRECT line pointers in
heap_prune_chain() and when LP_NORMAL line pointers refer to tuples
whose visibility status is not HEAPTUPLE_DEAD.
---
src/backend/access/heap/pruneheap.c | 24 ++++++++++++++++++++++--
src/backend/access/heap/vacuumlazy.c | 17 +----------------
src/include/access/heapam.h | 8 ++++++++
3 files changed, 31 insertions(+), 18 deletions(-)
diff --git a/src/backend/access/heap/pruneheap.c b/src/backend/access/heap/pruneheap.c
index be06699523..73fcc0081c 100644
--- a/src/backend/access/heap/pruneheap.c
+++ b/src/backend/access/heap/pruneheap.c
@@ -67,6 +67,9 @@ typedef struct
bool marked[MaxHeapTuplesPerPage + 1];
int ndeleted; /* Number of tuples deleted from the page */
+
+ /* Whether or not the page makes rel truncation unsafe */
+ bool hastup;
} PruneState;
/* Local functions */
@@ -273,6 +276,7 @@ heap_page_prune(Relation relation, Buffer buffer,
prstate.ndeleted = 0;
prstate.nchain_members = 0;
prstate.nchain_candidates = 0;
+ prstate.hastup = false;
/*
* If we will prepare to freeze tuples, consider that it might be possible
@@ -282,7 +286,7 @@ heap_page_prune(Relation relation, Buffer buffer,
presult->all_frozen = true;
else
presult->all_frozen = false;
-
+ presult->hastup = prstate.hastup;
/*
* presult->htsv is not initialized here because all ntuple spots in the
@@ -861,6 +865,8 @@ heap_prune_record_redirect(PruneState *prstate,
*/
if (was_normal)
prstate->ndeleted++;
+
+ prstate->hastup = true;
}
/* Record line pointer to be marked dead */
@@ -933,11 +939,15 @@ static void
heap_prune_record_unchanged(Page page, int8 *htsv, PruneState *prstate,
PruneResult *presult, OffsetNumber offnum)
{
- HeapTupleHeader htup = (HeapTupleHeader) PageGetItem(page, PageGetItemId(page, offnum));
+ HeapTupleHeader htup;
Assert(!prstate->marked[offnum]);
prstate->marked[offnum] = true;
+ presult->hastup = true; /* the page is not empty */
+
+ htup = (HeapTupleHeader) PageGetItem(page, PageGetItemId(page, offnum));
+
switch (htsv[offnum])
{
case HEAPTUPLE_LIVE:
@@ -1006,6 +1016,16 @@ heap_prune_record_unchanged_lp_dead(PruneState *prstate, OffsetNumber offnum)
{
Assert(!prstate->marked[offnum]);
prstate->marked[offnum] = true;
+
+ /*
+ * Deliberately don't set hastup for LP_DEAD items. We make the soft
+ * assumption that any LP_DEAD items encountered here will become
+ * LP_UNUSED later on, before count_nondeletable_pages is reached. If we
+ * don't make this assumption then rel truncation will only happen every
+ * other VACUUM, at most. Besides, VACUUM must treat
+ * hastup/nonempty_pages as provisional no matter how LP_DEAD items are
+ * handled (handled here, or handled later on).
+ */
}
diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index 679c6a866e..212d76045e 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -1419,7 +1419,6 @@ lazy_scan_prune(LVRelState *vacrel,
int lpdead_items,
live_tuples,
recently_dead_tuples;
- bool hastup = false;
bool all_visible;
TransactionId visibility_cutoff_xid;
uint8 actions = 0;
@@ -1500,23 +1499,11 @@ lazy_scan_prune(LVRelState *vacrel,
/* Redirect items mustn't be touched */
if (ItemIdIsRedirected(itemid))
- {
- /* page makes rel truncation unsafe */
- hastup = true;
continue;
- }
if (ItemIdIsDead(itemid))
{
/*
- * Deliberately don't set hastup for LP_DEAD items. We make the
- * soft assumption that any LP_DEAD items encountered here will
- * become LP_UNUSED later on, before count_nondeletable_pages is
- * reached. If we don't make this assumption then rel truncation
- * will only happen every other VACUUM, at most. Besides, VACUUM
- * must treat hastup/nonempty_pages as provisional no matter how
- * LP_DEAD items are handled (handled here, or handled later on).
- *
* Also deliberately delay unsetting all_visible until just before
* we return to lazy_scan_heap caller, as explained in full below.
* (This is another case where it's useful to anticipate that any
@@ -1631,8 +1618,6 @@ lazy_scan_prune(LVRelState *vacrel,
elog(ERROR, "unexpected HeapTupleSatisfiesVacuum result");
break;
}
-
- hastup = true; /* page makes rel truncation unsafe */
}
/*
@@ -1786,7 +1771,7 @@ lazy_scan_prune(LVRelState *vacrel,
vacrel->recently_dead_tuples += recently_dead_tuples;
/* Can't truncate this page */
- if (hastup)
+ if (presult.hastup)
vacrel->nonempty_pages = blkno + 1;
/* Did we find LP_DEAD items? */
diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h
index a7f5f19916..2311d01998 100644
--- a/src/include/access/heapam.h
+++ b/src/include/access/heapam.h
@@ -231,6 +231,14 @@ typedef struct PruneResult
*/
int8 htsv[MaxHeapTuplesPerPage + 1];
+ /*
+ * Whether or not the page makes rel truncation unsafe
+ *
+ * This is set to 'true', even if the page contains LP_DEAD items. VACUUM
+ * will remove them before attempting to truncate.
+ */
+ bool hastup;
+
/*
* Prepare to freeze in heap_page_prune(). lazy_scan_prune() will use the
* returned freeze plans to execute freezing.
--
2.40.1
--nehniapdxqvkrsct
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
filename="v10-0009-Save-dead-tuple-offsets-during-heap_page_prune.patch"
view thread (7+ messages)
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: [email protected]
Cc: [email protected]
Subject: Re: [PATCH v10 08/10] Set hastup in heap_page_prune
In-Reply-To: <no-message-id-82392@localhost>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox