Skip to content

Commit cbe04e5

Browse files
committed
Fix amcheck's handling of half-dead B-tree pages
amcheck incorrectly reported the following error if there were any half-dead pages in the index: ERROR: mismatch between parent key and child high key in index "amchecktest_id_idx" It's expected that a half-dead page does not have a downlink in the parent level, so skip the test. Reported-by: Konstantin Knizhnik <knizhnik@garret.ru> Reviewed-by: Peter Geoghegan <pg@bowt.ie> Reviewed-by: Mihail Nikalayeu <mihailnikalayeu@gmail.com> Discussion: https://www.postgresql.org/message-id/33e39552-6a2a-46f3-8b34-3f9f8004451f@garret.ru Backpatch-through: 14
1 parent c085aab commit cbe04e5

File tree

3 files changed

+20
-1
lines changed

3 files changed

+20
-1
lines changed

contrib/amcheck/verify_nbtree.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2268,7 +2268,7 @@ bt_child_highkey_check(BtreeCheckState *state,
22682268
* If we visit page with high key, check that it is equal to the
22692269
* target key next to corresponding downlink.
22702270
*/
2271-
if (!rightsplit && !P_RIGHTMOST(opaque))
2271+
if (!rightsplit && !P_RIGHTMOST(opaque) && !P_ISHALFDEAD(opaque))
22722272
{
22732273
BTPageOpaque topaque;
22742274
IndexTuple highkey;

src/test/modules/nbtree/expected/nbtree_half_dead_pages.out

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
-- This uses injection points to interrupt some page deletions
1212
set client_min_messages TO 'warning';
1313
create extension if not exists injection_points;
14+
create extension if not exists amcheck;
1415
reset client_min_messages;
1516
-- Make all injection points local to this process, for concurrency.
1617
SELECT injection_points_set_local();
@@ -57,6 +58,13 @@ select * from nbtree_half_dead_pages where id > 99998 and id < 120002;
5758
120001
5859
(4 rows)
5960

61+
-- Also check the index with amcheck
62+
select bt_index_parent_check('nbtree_half_dead_pages_id_idx'::regclass, true, true);
63+
bt_index_parent_check
64+
-----------------------
65+
66+
(1 row)
67+
6068
-- Finish the deletion and re-check
6169
vacuum nbtree_half_dead_pages;
6270
NOTICE: notice triggered for injection point nbtree-finish-half-dead-page-vacuum
@@ -69,3 +77,9 @@ select * from nbtree_half_dead_pages where id > 99998 and id < 120002;
6977
120001
7078
(4 rows)
7179

80+
select bt_index_parent_check('nbtree_half_dead_pages_id_idx'::regclass, true, true);
81+
bt_index_parent_check
82+
-----------------------
83+
84+
(1 row)
85+

src/test/modules/nbtree/sql/nbtree_half_dead_pages.sql

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
-- This uses injection points to interrupt some page deletions
1313
set client_min_messages TO 'warning';
1414
create extension if not exists injection_points;
15+
create extension if not exists amcheck;
1516
reset client_min_messages;
1617

1718
-- Make all injection points local to this process, for concurrency.
@@ -38,6 +39,10 @@ SELECT injection_points_detach('nbtree-leave-page-half-dead');
3839

3940
select * from nbtree_half_dead_pages where id > 99998 and id < 120002;
4041

42+
-- Also check the index with amcheck
43+
select bt_index_parent_check('nbtree_half_dead_pages_id_idx'::regclass, true, true);
44+
4145
-- Finish the deletion and re-check
4246
vacuum nbtree_half_dead_pages;
4347
select * from nbtree_half_dead_pages where id > 99998 and id < 120002;
48+
select bt_index_parent_check('nbtree_half_dead_pages_id_idx'::regclass, true, true);

0 commit comments

Comments
 (0)