| From: | Heikki Linnakangas <hlinnaka(at)iki(dot)fi> |
|---|---|
| To: | Peter Geoghegan <pg(at)bowt(dot)ie> |
| Cc: | Mihail Nikalayeu <mihailnikalayeu(at)gmail(dot)com>, Konstantin Knizhnik <knizhnik(at)garret(dot)ru>, akorotkov(at)postgresql(dot)org, aekorotkov(at)gmail(dot)com, PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org> |
| Subject: | Re: Bug in amcheck? |
| Date: | 2025-12-01 21:20:16 |
| Message-ID: | 2f4b281d-e88c-4bde-aabc-7805f4e99d7e@iki.fi |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | 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 | Content-Type | Size |
|---|---|---|
| v1-0001-Add-a-test-for-incomplete-splits-in-B-tree-indexe.patch | text/x-patch | 14.5 KB |
| v1-0002-Fix-amcheck-s-handling-of-incomplete-root-splits-.patch | text/x-patch | 3.2 KB |
| v1-0003-Add-a-test-for-half-dead-pages-in-B-tree-indexes.patch | text/x-patch | 6.8 KB |
| v1-0004-Fix-amcheck-s-handling-of-half-dead-B-tree-pages.patch | text/x-patch | 3.5 KB |
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Chao Li | 2025-12-01 21:35:34 | Re: show size of DSAs and dshash tables in pg_dsm_registry_allocations |
| Previous Message | Tomas Vondra | 2025-12-01 21:01:58 | Re: Is there value in having optimizer stats for joins/foreignkeys? |