summaryrefslogtreecommitdiff
path: root/src/backend/access/heap
diff options
context:
space:
mode:
authorPeter Geoghegan <pg@bowt.ie>2022-04-07 15:42:12 -0700
committerPeter Geoghegan <pg@bowt.ie>2022-04-07 15:42:12 -0700
commit10a8d138235b3b8cfbce8a0145526d9b9a80cc96 (patch)
tree30b4fee62e88402c1f5587a1054951f859a72e1e /src/backend/access/heap
parent9d9c02ccd1aea8e9131d8f4edb21bf1687e40782 (diff)
Truncate line pointer array during heap pruning.
Reclaim space from the line pointer array when heap pruning leaves behind a contiguous group of LP_UNUSED items at the end of the array. This happens during subsequent page defragmentation. Certain kinds of heap line pointer bloat are ameliorated by this new optimization. Follow-up work to commit 3c3b8a4b26, which taught VACUUM to truncate the line pointer array in about the same way during VACUUM's second pass over the heap. We now apply line pointer array truncation during both the first and the second pass over the heap made by VACUUM. We can also perform line pointer array truncation during opportunistic pruning. Matthias van de Meent, with small tweaks by me. Author: Matthias van de Meent <boekewurm+postgres@gmail.com> Discussion: https://postgr.es/m/CAEze2WjgaQc55Y5f5CQd3L=eS5CZcff2Obxp=O6pto8-f0hC4w@mail.gmail.com Discussion: https://postgr.es/m/CAEze2Wg36%2B4at2eWJNcYNiW2FJmht34x3YeX54ctUSs7kKoNcA%40mail.gmail.com
Diffstat (limited to 'src/backend/access/heap')
-rw-r--r--src/backend/access/heap/pruneheap.c4
-rw-r--r--src/backend/access/heap/vacuumlazy.c11
2 files changed, 11 insertions, 4 deletions
diff --git a/src/backend/access/heap/pruneheap.c b/src/backend/access/heap/pruneheap.c
index 4656f1b3db4..98d31de0031 100644
--- a/src/backend/access/heap/pruneheap.c
+++ b/src/backend/access/heap/pruneheap.c
@@ -244,7 +244,9 @@ heap_page_prune_opt(Relation relation, Buffer buffer)
* Prune and repair fragmentation in the specified page.
*
* Caller must have pin and buffer cleanup lock on the page. Note that we
- * don't update the FSM information for page on caller's behalf.
+ * don't update the FSM information for page on caller's behalf. Caller might
+ * also need to account for a reduction in the length of the line pointer
+ * array following array truncation by us.
*
* vistest is used to distinguish whether tuples are DEAD or RECENTLY_DEAD
* (see heap_prune_satisfies_vacuum and
diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index 092b739dda9..e1cac74e620 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -223,7 +223,7 @@ typedef struct LVRelState
*/
typedef struct LVPagePruneState
{
- bool hastup; /* Page is truncatable? */
+ bool hastup; /* Page prevents rel truncation? */
bool has_lpdead_items; /* includes existing LP_DEAD items */
/*
@@ -1393,7 +1393,7 @@ lazy_scan_skip(LVRelState *vacrel, Buffer *vmbuffer, BlockNumber next_block,
*
* It's necessary to consider new pages as a special case, since the rules for
* maintaining the visibility map and FSM with empty pages are a little
- * different (though new pages can be truncated based on the usual rules).
+ * different (though new pages can be truncated away during rel truncation).
*
* Empty pages are not really a special case -- they're just heap pages that
* have no allocated tuples (including even LP_UNUSED items). You might
@@ -1561,6 +1561,11 @@ lazy_scan_prune(LVRelState *vacrel,
Assert(BufferGetBlockNumber(buf) == blkno);
+ /*
+ * maxoff might be reduced following line pointer array truncation in
+ * heap_page_prune. That's safe for us to ignore, since the reclaimed
+ * space will continue to look like LP_UNUSED items below.
+ */
maxoff = PageGetMaxOffsetNumber(page);
retry:
@@ -1768,7 +1773,7 @@ retry:
* Check tuple left behind after pruning to see if needs to be frozen
* now.
*/
- prunestate->hastup = true; /* page won't be truncatable */
+ prunestate->hastup = true; /* page makes rel truncation unsafe */
if (heap_prepare_freeze_tuple(tuple.t_data,
vacrel->relfrozenxid,
vacrel->relminmxid,