Re: Bug in amcheck?
Heikki Linnakangas <hlinnaka@iki.fi>
From: Heikki Linnakangas <hlinnaka@iki.fi>
To: Peter Geoghegan <pg@bowt.ie>
Cc: Mihail Nikalayeu <mihailnikalayeu@gmail.com>,
Konstantin Knizhnik <knizhnik@garret.ru>, akorotkov@postgresql.org,
aekorotkov@gmail.com, PostgreSQL Hackers <pgsql-hackers@lists.postgresql.org>
Date: 2025-12-01T21:20:16Z
Lists: pgsql-hackers
Commits
Same data as JSON:
GET /api/v1/messages/:b64id/commits
the thread's linked commits as JSON, with link sources.
API reference →
-
Fix amcheck's handling of half-dead B-tree pages
- fbb4b607832d 14.21 landed
- 7792bdc45860 15.16 landed
- 1829016268c3 16.12 landed
- e8ae594458a3 17.8 landed
- 19e786727c4f 18.2 landed
- cbe04e5d729f 19 (unreleased) landed
-
Fix amcheck's handling of incomplete root splits in B-tree
- a4cb21ea9cd7 14.21 landed
- 721b58fbec5f 15.16 landed
- f2a6df9fd56d 16.12 landed
- 5a2d1df00718 17.8 landed
- 50c63ebb05fc 18.2 landed
- 6c05ef5729c0 19 (unreleased) landed
-
Add a test for half-dead pages in B-tree indexes
- c085aab27819 19 (unreleased) landed
-
Add a test for incomplete splits in B-tree indexes
- 1e4e5783e7d7 19 (unreleased) landed
-
Improve checking of child pages in contrib/amcheck.
- d114cc538715 13.0 cited
Attachments
- v1-0001-Add-a-test-for-incomplete-splits-in-B-tree-indexe.patch (text/x-patch) patch v1-0001
- v1-0002-Fix-amcheck-s-handling-of-incomplete-root-splits-.patch (text/x-patch) patch v1-0002
- v1-0003-Add-a-test-for-half-dead-pages-in-B-tree-indexes.patch (text/x-patch) patch v1-0003
- v1-0004-Fix-amcheck-s-handling-of-half-dead-B-tree-pages.patch (text/x-patch) patch v1-0004
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