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

Commit5cd7eb1

Browse files
Add various assertions to heap pruning code.
These assertions document (and verify) our high level assumptions abouthow pruning can and cannot affect existing items from target heap pages.For example, one of the new assertions verifies that pruning does notset a heap-only tuple to LP_DEAD.Author: Peter Geoghegan <pg@bowt.ie>Reviewed-By: Andres Freund <andres@anarazel.de>Discussion:https://postgr.es/m/CAH2-Wz=vhvBx1GjF+oueHh8YQcHoQYrMi0F0zFMHEr8yc4sCoA@mail.gmail.com
1 parent9588622 commit5cd7eb1

File tree

1 file changed

+80
-4
lines changed

1 file changed

+80
-4
lines changed

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

Lines changed: 80 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -844,39 +844,115 @@ heap_page_prune_execute(Buffer buffer,
844844
{
845845
Pagepage= (Page)BufferGetPage(buffer);
846846
OffsetNumber*offnum;
847-
inti;
847+
HeapTupleHeaderhtupPG_USED_FOR_ASSERTS_ONLY;
848848

849849
/* Shouldn't be called unless there's something to do */
850850
Assert(nredirected>0||ndead>0||nunused>0);
851851

852852
/* Update all redirected line pointers */
853853
offnum=redirected;
854-
for (i=0;i<nredirected;i++)
854+
for (inti=0;i<nredirected;i++)
855855
{
856856
OffsetNumberfromoff=*offnum++;
857857
OffsetNumbertooff=*offnum++;
858858
ItemIdfromlp=PageGetItemId(page,fromoff);
859+
ItemIdtolpPG_USED_FOR_ASSERTS_ONLY;
860+
861+
#ifdefUSE_ASSERT_CHECKING
862+
863+
/*
864+
* Any existing item that we set as an LP_REDIRECT (any 'from' item)
865+
* must be the first item from a HOT chain. If the item has tuple
866+
* storage then it can't be a heap-only tuple. Otherwise we are just
867+
* maintaining an existing LP_REDIRECT from an existing HOT chain that
868+
* has been pruned at least once before now.
869+
*/
870+
if (!ItemIdIsRedirected(fromlp))
871+
{
872+
Assert(ItemIdHasStorage(fromlp)&&ItemIdIsNormal(fromlp));
873+
874+
htup= (HeapTupleHeader)PageGetItem(page,fromlp);
875+
Assert(!HeapTupleHeaderIsHeapOnly(htup));
876+
}
877+
else
878+
{
879+
/* We shouldn't need to redundantly set the redirect */
880+
Assert(ItemIdGetRedirect(fromlp)!=tooff);
881+
}
882+
883+
/*
884+
* The item that we're about to set as an LP_REDIRECT (the 'from'
885+
* item) will point to an existing item (the 'to' item) that is
886+
* already a heap-only tuple. There can be at most one LP_REDIRECT
887+
* item per HOT chain.
888+
*
889+
* We need to keep around an LP_REDIRECT item (after original
890+
* non-heap-only root tuple gets pruned away) so that it's always
891+
* possible for VACUUM to easily figure out what TID to delete from
892+
* indexes when an entire HOT chain becomes dead. A heap-only tuple
893+
* can never become LP_DEAD; an LP_REDIRECT item or a regular heap
894+
* tuple can.
895+
*/
896+
tolp=PageGetItemId(page,tooff);
897+
Assert(ItemIdHasStorage(tolp)&&ItemIdIsNormal(tolp));
898+
htup= (HeapTupleHeader)PageGetItem(page,tolp);
899+
Assert(HeapTupleHeaderIsHeapOnly(htup));
900+
#endif
859901

860902
ItemIdSetRedirect(fromlp,tooff);
861903
}
862904

863905
/* Update all now-dead line pointers */
864906
offnum=nowdead;
865-
for (i=0;i<ndead;i++)
907+
for (inti=0;i<ndead;i++)
866908
{
867909
OffsetNumberoff=*offnum++;
868910
ItemIdlp=PageGetItemId(page,off);
869911

912+
#ifdefUSE_ASSERT_CHECKING
913+
914+
/*
915+
* An LP_DEAD line pointer must be left behind when the original item
916+
* (which is dead to everybody) could still be referenced by a TID in
917+
* an index. This should never be necessary with any individual
918+
* heap-only tuple item, though. (It's not clear how much of a problem
919+
* that would be, but there is no reason to allow it.)
920+
*/
921+
if (ItemIdHasStorage(lp))
922+
{
923+
Assert(ItemIdIsNormal(lp));
924+
htup= (HeapTupleHeader)PageGetItem(page,lp);
925+
Assert(!HeapTupleHeaderIsHeapOnly(htup));
926+
}
927+
else
928+
{
929+
/* Whole HOT chain becomes dead */
930+
Assert(ItemIdIsRedirected(lp));
931+
}
932+
#endif
933+
870934
ItemIdSetDead(lp);
871935
}
872936

873937
/* Update all now-unused line pointers */
874938
offnum=nowunused;
875-
for (i=0;i<nunused;i++)
939+
for (inti=0;i<nunused;i++)
876940
{
877941
OffsetNumberoff=*offnum++;
878942
ItemIdlp=PageGetItemId(page,off);
879943

944+
#ifdefUSE_ASSERT_CHECKING
945+
946+
/*
947+
* Only heap-only tuples can become LP_UNUSED during pruning. They
948+
* don't need to be left in place as LP_DEAD items until VACUUM gets
949+
* around to doing index vacuuming.
950+
*/
951+
Assert(ItemIdHasStorage(lp)&&ItemIdIsNormal(lp));
952+
htup= (HeapTupleHeader)PageGetItem(page,lp);
953+
Assert(HeapTupleHeaderIsHeapOnly(htup));
954+
#endif
955+
880956
ItemIdSetUnused(lp);
881957
}
882958

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp