Re: Bug in amcheck? - Mailing list pgsql-hackers

From Heikki Linnakangas
Subject Re: Bug in amcheck?
Date
Msg-id 2f4b281d-e88c-4bde-aabc-7805f4e99d7e@iki.fi
Whole thread Raw
In response to Re: Bug in amcheck?  (Heikki Linnakangas <hlinnaka@iki.fi>)
List pgsql-hackers
On 26/11/2025 10:20, Heikki Linnakangas wrote:
> On 25/11/2025 22:51, Peter Geoghegan wrote:
>> In short, I think that we need to track something like
>> BtreeCheckState.previncompletesplit, but for half-dead pages. And then
>> actually use that within bt_child_highkey_check, to avoid spurious
>> false-positive reports of corruption.
> 
> I think it's even simpler than that, and we can just do this:
> 
> --- a/contrib/amcheck/verify_nbtree.c
> +++ b/contrib/amcheck/verify_nbtree.c
> @@ -2268,7 +2268,7 @@ bt_child_highkey_check(BtreeCheckState *state,
>            * If we visit page with high key, check that it is equal to the
>            * target key next to corresponding downlink.
>            */
> -        if (!rightsplit && !P_RIGHTMOST(opaque))
> +        if (!rightsplit && !P_RIGHTMOST(opaque) && !P_ISHALFDEAD(opaque))
>           {
>               BTPageOpaque topaque;
>               IndexTuple    highkey;
> 
> 
> Both BTP_HALF_DEAD and BTP_INCOMPLETE_SPLIT indicate that a downlink is 
> missing, but they work slightly differently. If a page is marked as 
> BTP_INCOMPLETE_SPLIT, it means that its right sibling has no downlink, 
> but if a page is marked as BTP_HALF_DEAD, it means that the page itself 
> has no downlink.

Ok, here's a proper patch with tests. The patch itself is the above 
one-liner. It's in patch 0004.

While testing this, I bumped into another similar amcheck bug: if the 
root page split is interrupted, verify_btree() complains:

ERROR:  block 3 is not true root in index "nbtree_incomplete_splits_i_idx"

Attached patch 0002 contains a fix and a test for that. The fix for that 
is also one-liner.


Summary of the patches:

Patch 0001 adds an injection point test for incomplete splits. We 
already had such a test for GIN, which handles incomplete splits the 
same way as B-tree. I copy-pasted and adapted the GIN test for B-tree. 
This was an easy way to increase our test coverage.

Patch 0002 fixes the incomplete-root-split bug in amcheck. It modifies 
the test added in patch 0001 to cover the bug fix.

Patch 0003 adds a test for half-dead pages, similar to what 0001 did for 
incomplete splits.

Patch 0004 fixes the bogus half-deaf-page error in amcheck, i.e. the 
issue that started this thread. It modifies the test introduced in patch 
0003 to add amcheck calls, to cover the bug fix.

- Heikki

Attachment

pgsql-hackers by date:

Previous
From: Tomas Vondra
Date:
Subject: Re: Is there value in having optimizer stats for joins/foreignkeys?
Next
From: Chao Li
Date:
Subject: Re: show size of DSAs and dshash tables in pg_dsm_registry_allocations