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

Commitbb42bfb

Browse files
committed
Assert redirect pointers are sensible after heap_page_prune().
Corruption of redirect item pointers often only becomes visible well afterbeing corrupted, as e.g. bug #17255 shows: In the original reproducer,gigabyte of WAL were between the source of the corruption and the corruptionbecoming visible.To make it easier to find / prevent such bugs, verify whether redirectpointers are sensible at the end of heap_page_prune_execute().5cd7eb1introduced related assertions while modifying the page, but they can't easilydetect marking the target of an existing redirect as unused. Sometimes thecorruption will be detected later, but that's harder to diagnose.Author: Andres Freund <andres@andres@anarazel.de>Reviewed-By: Peter Geoghegan <pg@bowt.ie>Discussion:https://postgr.es/m/20211122175914.ayk6gg6nvdwuhrzb@alap3.anarazel.de
1 parent18b87b2 commitbb42bfb

File tree

1 file changed

+57
-0
lines changed

1 file changed

+57
-0
lines changed

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

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ static void heap_prune_record_redirect(PruneState *prstate,
8888
OffsetNumberoffnum,OffsetNumberrdoffnum);
8989
staticvoidheap_prune_record_dead(PruneState*prstate,OffsetNumberoffnum);
9090
staticvoidheap_prune_record_unused(PruneState*prstate,OffsetNumberoffnum);
91+
staticvoidpage_verify_redirects(Pagepage);
9192

9293

9394
/*
@@ -959,6 +960,10 @@ heap_page_prune_execute(Buffer buffer,
959960
* indexes when an entire HOT chain becomes dead. A heap-only tuple
960961
* can never become LP_DEAD; an LP_REDIRECT item or a regular heap
961962
* tuple can.
963+
*
964+
* This check may miss problems, e.g. the target of a redirect could
965+
* be marked as unused subsequently. The page_verify_redirects() check
966+
* below will catch such problems.
962967
*/
963968
tolp=PageGetItemId(page,tooff);
964969
Assert(ItemIdHasStorage(tolp)&&ItemIdIsNormal(tolp));
@@ -1028,6 +1033,58 @@ heap_page_prune_execute(Buffer buffer,
10281033
* whether it has free pointers.
10291034
*/
10301035
PageRepairFragmentation(page);
1036+
1037+
/*
1038+
* Now that the page has been modified, assert that redirect items still
1039+
* point to valid targets.
1040+
*/
1041+
page_verify_redirects(page);
1042+
}
1043+
1044+
1045+
/*
1046+
* If built with assertions, verify that all LP_REDIRECT items point to a
1047+
* valid item.
1048+
*
1049+
* One way that bugs related to HOT pruning show is redirect items pointing to
1050+
* removed tuples. It's not trivial to reliably check that marking an item
1051+
* unused will not orphan a redirect item during heap_prune_chain() /
1052+
* heap_page_prune_execute(), so we additionally check the whole page after
1053+
* pruning. Without this check such bugs would typically only cause asserts
1054+
* later, potentially well after the corruption has been introduced.
1055+
*
1056+
* Also check comments in heap_page_prune_execute()'s redirection loop.
1057+
*/
1058+
staticvoid
1059+
page_verify_redirects(Pagepage)
1060+
{
1061+
#ifdefUSE_ASSERT_CHECKING
1062+
OffsetNumberoffnum;
1063+
OffsetNumbermaxoff;
1064+
1065+
maxoff=PageGetMaxOffsetNumber(page);
1066+
for (offnum=FirstOffsetNumber;
1067+
offnum <=maxoff;
1068+
offnum=OffsetNumberNext(offnum))
1069+
{
1070+
ItemIditemid=PageGetItemId(page,offnum);
1071+
OffsetNumbertargoff;
1072+
ItemIdtargitem;
1073+
HeapTupleHeaderhtup;
1074+
1075+
if (!ItemIdIsRedirected(itemid))
1076+
continue;
1077+
1078+
targoff=ItemIdGetRedirect(itemid);
1079+
targitem=PageGetItemId(page,targoff);
1080+
1081+
Assert(ItemIdIsUsed(targitem));
1082+
Assert(ItemIdIsNormal(targitem));
1083+
Assert(ItemIdHasStorage(targitem));
1084+
htup= (HeapTupleHeader)PageGetItem(page,targitem);
1085+
Assert(HeapTupleHeaderIsHeapOnly(htup));
1086+
}
1087+
#endif
10311088
}
10321089

10331090

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp