mirror of
https://github.com/postgres/postgres.git
synced 2025-12-02 23:42:46 +03:00
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
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
-- This uses injection points to interrupt some page deletions
|
||||
set client_min_messages TO 'warning';
|
||||
create extension if not exists injection_points;
|
||||
create extension if not exists amcheck;
|
||||
reset client_min_messages;
|
||||
-- Make all injection points local to this process, for concurrency.
|
||||
SELECT injection_points_set_local();
|
||||
@@ -57,6 +58,13 @@ select * from nbtree_half_dead_pages where id > 99998 and id < 120002;
|
||||
120001
|
||||
(4 rows)
|
||||
|
||||
-- Also check the index with amcheck
|
||||
select bt_index_parent_check('nbtree_half_dead_pages_id_idx'::regclass, true, true);
|
||||
bt_index_parent_check
|
||||
-----------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
-- Finish the deletion and re-check
|
||||
vacuum nbtree_half_dead_pages;
|
||||
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;
|
||||
120001
|
||||
(4 rows)
|
||||
|
||||
select bt_index_parent_check('nbtree_half_dead_pages_id_idx'::regclass, true, true);
|
||||
bt_index_parent_check
|
||||
-----------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
-- This uses injection points to interrupt some page deletions
|
||||
set client_min_messages TO 'warning';
|
||||
create extension if not exists injection_points;
|
||||
create extension if not exists amcheck;
|
||||
reset client_min_messages;
|
||||
|
||||
-- Make all injection points local to this process, for concurrency.
|
||||
@@ -38,6 +39,10 @@ SELECT injection_points_detach('nbtree-leave-page-half-dead');
|
||||
|
||||
select * from nbtree_half_dead_pages where id > 99998 and id < 120002;
|
||||
|
||||
-- Also check the index with amcheck
|
||||
select bt_index_parent_check('nbtree_half_dead_pages_id_idx'::regclass, true, true);
|
||||
|
||||
-- Finish the deletion and re-check
|
||||
vacuum nbtree_half_dead_pages;
|
||||
select * from nbtree_half_dead_pages where id > 99998 and id < 120002;
|
||||
select bt_index_parent_check('nbtree_half_dead_pages_id_idx'::regclass, true, true);
|
||||
|
||||
Reference in New Issue
Block a user