Skip to content

Commit c87aff0

Browse files
committed
amcheck: Generalize one of the recently-added update chain checks.
Commit bbc1376 checked that if a redirected line pointer pointed to a tuple, the tuple should be marked both HEAP_ONLY_TUPLE and HEAP_UPDATED. But Andres Freund pointed out that *any* tuple that is marked HEAP_ONLY_TUPLE should be marked HEAP_UPDATED, not just one that is the target of a redirected line pointer. Do that instead. To see why this is better, consider a redirect line pointer A which points to a heap-only tuple B which points (via CTID) to another heap-only tuple C. With the old code, we'd complain if B was not marked HEAP_UPDATED, but with this change, we'll complain if either B or C is not marked HEAP_UPDATED. (Note that, with or without this commit, if either B or C were not marked HEAP_ONLY_TUPLE, we would also complain about that.) Discussion: http://postgr.es/m/CA%2BTgmobLypZx%3DcOH%2ByY1GZmCruaoucHm77A6y_-Bo%3Dh-_3H28g%40mail.gmail.com
1 parent 80d5e3a commit c87aff0

File tree

2 files changed

+14
-17
lines changed

2 files changed

+14
-17
lines changed

contrib/amcheck/verify_heapam.c

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -624,17 +624,6 @@ verify_heapam(PG_FUNCTION_ARGS)
624624
(unsigned) nextoffnum));
625625
}
626626

627-
/*
628-
* Redirects are created by updates, so successor should be
629-
* the result of an update.
630-
*/
631-
if ((next_htup->t_infomask & HEAP_UPDATED) == 0)
632-
{
633-
report_corruption(&ctx,
634-
psprintf("redirected line pointer points to a non-heap-updated tuple at offset %u",
635-
(unsigned) nextoffnum));
636-
}
637-
638627
/* HOT chains should not intersect. */
639628
if (predecessor[nextoffnum] != InvalidOffsetNumber)
640629
{
@@ -954,6 +943,15 @@ check_tuple_header(HeapCheckContext *ctx)
954943
*/
955944
}
956945

946+
if (HeapTupleHeaderIsHeapOnly(tuphdr) &&
947+
((tuphdr->t_infomask & HEAP_UPDATED) == 0))
948+
{
949+
report_corruption(ctx,
950+
psprintf("tuple is heap only, but not the result of an update"));
951+
952+
/* Here again, we can still perform further checks. */
953+
}
954+
957955
if (infomask & HEAP_HASNULL)
958956
expected_hoff = MAXALIGN(SizeofHeapTupleHeader + BITMAPLEN(ctx->natts));
959957
else

src/bin/pg_amcheck/t/004_verify_heapam.pl

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -617,12 +617,10 @@ sub header
617617
}
618618
elsif ($offnum == 17)
619619
{
620-
# at offnum 19 we will unset HEAP_ONLY_TUPLE and HEAP_UPDATED flags.
620+
# at offnum 19 we will unset HEAP_ONLY_TUPLE flag
621621
die "offnum $offnum should be a redirect" if defined $tup;
622622
push @expected,
623623
qr/${header}redirected line pointer points to a non-heap-only tuple at offset \d+/;
624-
push @expected,
625-
qr/${header}redirected line pointer points to a non-heap-updated tuple at offset \d+/;
626624
}
627625
elsif ($offnum == 18)
628626
{
@@ -637,10 +635,9 @@ sub header
637635
}
638636
elsif ($offnum == 19)
639637
{
640-
# unset HEAP_ONLY_TUPLE and HEAP_UPDATED flag, so that update chain
641-
# validation will complain about offset 17
638+
# unset HEAP_ONLY_TUPLE flag, so that update chain validation will
639+
# complain about offset 17
642640
$tup->{t_infomask2} &= ~HEAP_ONLY_TUPLE;
643-
$tup->{t_infomask} &= ~HEAP_UPDATED;
644641
}
645642
elsif ($offnum == 22)
646643
{
@@ -688,6 +685,8 @@ sub header
688685
$tup->{t_infomask2} |= HEAP_ONLY_TUPLE;
689686
push @expected,
690687
qr/${header}tuple is root of chain but is marked as heap-only tuple/;
688+
push @expected,
689+
qr/${header}tuple is heap only, but not the result of an update/;
691690
}
692691
elsif ($offnum == 33)
693692
{

0 commit comments

Comments
 (0)