Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit10a8d13

Browse files
Truncate line pointer array during heap pruning.
Reclaim space from the line pointer array when heap pruning leavesbehind a contiguous group of LP_UNUSED items at the end of the array.This happens during subsequent page defragmentation. Certain kinds ofheap line pointer bloat are ameliorated by this new optimization.Follow-up work to commit3c3b8a4, which taught VACUUM to truncate theline pointer array in about the same way during VACUUM's second passover the heap. We now apply line pointer array truncation during boththe first and the second pass over the heap made by VACUUM. We can alsoperform 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.comDiscussion:https://postgr.es/m/CAEze2Wg36%2B4at2eWJNcYNiW2FJmht34x3YeX54ctUSs7kKoNcA%40mail.gmail.com
1 parent9d9c02c commit10a8d13

File tree

3 files changed

+33
-17
lines changed

3 files changed

+33
-17
lines changed

‎src/backend/access/heap/pruneheap.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,9 @@ heap_page_prune_opt(Relation relation, Buffer buffer)
244244
* Prune and repair fragmentation in the specified page.
245245
*
246246
* Caller must have pin and buffer cleanup lock on the page. Note that we
247-
* don't update the FSM information for page on caller's behalf.
247+
* don't update the FSM information for page on caller's behalf. Caller might
248+
* also need to account for a reduction in the length of the line pointer
249+
* array following array truncation by us.
248250
*
249251
* vistest is used to distinguish whether tuples are DEAD or RECENTLY_DEAD
250252
* (see heap_prune_satisfies_vacuum and

‎src/backend/access/heap/vacuumlazy.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ typedef struct LVRelState
223223
*/
224224
typedefstructLVPagePruneState
225225
{
226-
boolhastup;/* Pageis truncatable? */
226+
boolhastup;/* Pageprevents rel truncation? */
227227
boolhas_lpdead_items;/* includes existing LP_DEAD items */
228228

229229
/*
@@ -1393,7 +1393,7 @@ lazy_scan_skip(LVRelState *vacrel, Buffer *vmbuffer, BlockNumber next_block,
13931393
*
13941394
* It's necessary to consider new pages as a special case, since the rules for
13951395
* maintaining the visibility map and FSM with empty pages are a little
1396-
* different (though new pages can be truncatedbased on the usual rules).
1396+
* different (though new pages can be truncatedaway during rel truncation).
13971397
*
13981398
* Empty pages are not really a special case -- they're just heap pages that
13991399
* have no allocated tuples (including even LP_UNUSED items). You might
@@ -1561,6 +1561,11 @@ lazy_scan_prune(LVRelState *vacrel,
15611561

15621562
Assert(BufferGetBlockNumber(buf)==blkno);
15631563

1564+
/*
1565+
* maxoff might be reduced following line pointer array truncation in
1566+
* heap_page_prune. That's safe for us to ignore, since the reclaimed
1567+
* space will continue to look like LP_UNUSED items below.
1568+
*/
15641569
maxoff=PageGetMaxOffsetNumber(page);
15651570

15661571
retry:
@@ -1768,7 +1773,7 @@ lazy_scan_prune(LVRelState *vacrel,
17681773
* Check tuple left behind after pruning to see if needs to be frozen
17691774
* now.
17701775
*/
1771-
prunestate->hastup= true;/* pagewon't be truncatable */
1776+
prunestate->hastup= true;/* pagemakes rel truncation unsafe */
17721777
if (heap_prepare_freeze_tuple(tuple.t_data,
17731778
vacrel->relfrozenxid,
17741779
vacrel->relminmxid,

‎src/backend/storage/page/bufpage.c

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -688,22 +688,14 @@ compactify_tuples(itemIdCompact itemidbase, int nitems, Page page, bool presorte
688688
*
689689
* This routine is usable for heap pages only, but see PageIndexMultiDelete.
690690
*
691-
* Never removes unused line pointers. PageTruncateLinePointerArray can
692-
* safely remove some unused line pointers. It ought to be safe for this
693-
* routine to free unused line pointers in roughly the same way, but it's not
694-
* clear that that would be beneficial.
695-
*
696-
* PageTruncateLinePointerArray is only called during VACUUM's second pass
697-
* over the heap. Any unused line pointers that it sees are likely to have
698-
* been set to LP_UNUSED (from LP_DEAD) immediately before the time it is
699-
* called. On the other hand, many tables have the vast majority of all
700-
* required pruning performed opportunistically (not during VACUUM). And so
701-
* there is, in general, a good chance that even large groups of unused line
702-
* pointers that we see here will be recycled quickly.
691+
* This routine removes unused line pointers from the end of the line pointer
692+
* array. This is possible when dead heap-only tuples get removed by pruning,
693+
* especially when there were HOT chains with several tuples each beforehand.
703694
*
704695
* Caller had better have a full cleanup lock on page's buffer. As a side
705696
* effect the page's PD_HAS_FREE_LINES hint bit will be set or unset as
706-
* needed.
697+
* needed. Caller might also need to account for a reduction in the length of
698+
* the line pointer array following array truncation.
707699
*/
708700
void
709701
PageRepairFragmentation(Pagepage)
@@ -718,6 +710,7 @@ PageRepairFragmentation(Page page)
718710
intnline,
719711
nstorage,
720712
nunused;
713+
OffsetNumberfinalusedlp=InvalidOffsetNumber;
721714
inti;
722715
Sizetotallen;
723716
boolpresorted= true;/* For now */
@@ -771,10 +764,13 @@ PageRepairFragmentation(Page page)
771764
totallen+=itemidptr->alignedlen;
772765
itemidptr++;
773766
}
767+
768+
finalusedlp=i;/* Could be the final non-LP_UNUSED item */
774769
}
775770
else
776771
{
777772
/* Unused entries should have lp_len = 0, but make sure */
773+
Assert(!ItemIdHasStorage(lp));
778774
ItemIdSetUnused(lp);
779775
nunused++;
780776
}
@@ -798,6 +794,19 @@ PageRepairFragmentation(Page page)
798794
compactify_tuples(itemidbase,nstorage,page,presorted);
799795
}
800796

797+
if (finalusedlp!=nline)
798+
{
799+
/* The last line pointer is not the last used line pointer */
800+
intnunusedend=nline-finalusedlp;
801+
802+
Assert(nunused >=nunusedend&&nunusedend>0);
803+
804+
/* remove trailing unused line pointers from the count */
805+
nunused-=nunusedend;
806+
/* truncate the line pointer array */
807+
((PageHeader)page)->pd_lower-= (sizeof(ItemIdData)*nunusedend);
808+
}
809+
801810
/* Set hint bit for PageAddItemExtended */
802811
if (nunused>0)
803812
PageSetHasFreeLinePointers(page);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp