mirror of https://github.com/postgres/postgres
To increase our test coverage in general, and because I will use this in the next commit to test a bug we currently have in amcheck. Reviewed-by: Peter Geoghegan <pg@bowt.ie> Discussion: https://www.postgresql.org/message-id/33e39552-6a2a-46f3-8b34-3f9f8004451f@garret.rupull/255/head
parent
6c05ef5729
commit
c085aab278
@ -0,0 +1,71 @@ |
|||||||
|
-- |
||||||
|
-- Test half-dead pages in B-tree indexes. |
||||||
|
-- |
||||||
|
-- Half-dead pages is an intermediate state while vacuum is deleting a |
||||||
|
-- page. You can encounter them if you query concurrently with vacuum, |
||||||
|
-- or if vacuum is interrupted while it's deleting a page. A B-tree |
||||||
|
-- with half-dead pages is a valid state, but they rarely observed by |
||||||
|
-- other backends in practice because, so it's good to have some |
||||||
|
-- targeted tests to exercise them. |
||||||
|
-- |
||||||
|
-- This uses injection points to interrupt some page deletions |
||||||
|
set client_min_messages TO 'warning'; |
||||||
|
create extension if not exists injection_points; |
||||||
|
reset client_min_messages; |
||||||
|
-- Make all injection points local to this process, for concurrency. |
||||||
|
SELECT injection_points_set_local(); |
||||||
|
injection_points_set_local |
||||||
|
---------------------------- |
||||||
|
|
||||||
|
(1 row) |
||||||
|
|
||||||
|
-- Use the index for all the queries |
||||||
|
set enable_seqscan=off; |
||||||
|
-- Print a NOTICE whenever a half-dead page is deleted |
||||||
|
SELECT injection_points_attach('nbtree-finish-half-dead-page-vacuum', 'notice'); |
||||||
|
injection_points_attach |
||||||
|
------------------------- |
||||||
|
|
||||||
|
(1 row) |
||||||
|
|
||||||
|
create table nbtree_half_dead_pages(id bigint) with (autovacuum_enabled = off); |
||||||
|
insert into nbtree_half_dead_pages SELECT g from generate_series(1, 150000) g; |
||||||
|
create index nbtree_half_dead_pages_id_idx on nbtree_half_dead_pages using btree (id); |
||||||
|
delete from nbtree_half_dead_pages where id > 100000 and id < 120000; |
||||||
|
-- Run VACUUM and interrupt it so that it leaves behind a half-dead page |
||||||
|
SELECT injection_points_attach('nbtree-leave-page-half-dead', 'error'); |
||||||
|
injection_points_attach |
||||||
|
------------------------- |
||||||
|
|
||||||
|
(1 row) |
||||||
|
|
||||||
|
vacuum nbtree_half_dead_pages; |
||||||
|
ERROR: error triggered for injection point nbtree-leave-page-half-dead |
||||||
|
CONTEXT: while vacuuming index "nbtree_half_dead_pages_id_idx" of relation "public.nbtree_half_dead_pages" |
||||||
|
SELECT injection_points_detach('nbtree-leave-page-half-dead'); |
||||||
|
injection_points_detach |
||||||
|
------------------------- |
||||||
|
|
||||||
|
(1 row) |
||||||
|
|
||||||
|
select * from nbtree_half_dead_pages where id > 99998 and id < 120002; |
||||||
|
id |
||||||
|
-------- |
||||||
|
99999 |
||||||
|
100000 |
||||||
|
120000 |
||||||
|
120001 |
||||||
|
(4 rows) |
||||||
|
|
||||||
|
-- Finish the deletion and re-check |
||||||
|
vacuum nbtree_half_dead_pages; |
||||||
|
NOTICE: notice triggered for injection point nbtree-finish-half-dead-page-vacuum |
||||||
|
select * from nbtree_half_dead_pages where id > 99998 and id < 120002; |
||||||
|
id |
||||||
|
-------- |
||||||
|
99999 |
||||||
|
100000 |
||||||
|
120000 |
||||||
|
120001 |
||||||
|
(4 rows) |
||||||
|
|
||||||
@ -0,0 +1,43 @@ |
|||||||
|
-- |
||||||
|
-- Test half-dead pages in B-tree indexes. |
||||||
|
-- |
||||||
|
-- Half-dead pages is an intermediate state while vacuum is deleting a |
||||||
|
-- page. You can encounter them if you query concurrently with vacuum, |
||||||
|
-- or if vacuum is interrupted while it's deleting a page. A B-tree |
||||||
|
-- with half-dead pages is a valid state, but they rarely observed by |
||||||
|
-- other backends in practice because, so it's good to have some |
||||||
|
-- targeted tests to exercise them. |
||||||
|
-- |
||||||
|
|
||||||
|
-- This uses injection points to interrupt some page deletions |
||||||
|
set client_min_messages TO 'warning'; |
||||||
|
create extension if not exists injection_points; |
||||||
|
reset client_min_messages; |
||||||
|
|
||||||
|
-- Make all injection points local to this process, for concurrency. |
||||||
|
SELECT injection_points_set_local(); |
||||||
|
|
||||||
|
-- Use the index for all the queries |
||||||
|
set enable_seqscan=off; |
||||||
|
|
||||||
|
-- Print a NOTICE whenever a half-dead page is deleted |
||||||
|
SELECT injection_points_attach('nbtree-finish-half-dead-page-vacuum', 'notice'); |
||||||
|
|
||||||
|
create table nbtree_half_dead_pages(id bigint) with (autovacuum_enabled = off); |
||||||
|
|
||||||
|
insert into nbtree_half_dead_pages SELECT g from generate_series(1, 150000) g; |
||||||
|
|
||||||
|
create index nbtree_half_dead_pages_id_idx on nbtree_half_dead_pages using btree (id); |
||||||
|
|
||||||
|
delete from nbtree_half_dead_pages where id > 100000 and id < 120000; |
||||||
|
|
||||||
|
-- Run VACUUM and interrupt it so that it leaves behind a half-dead page |
||||||
|
SELECT injection_points_attach('nbtree-leave-page-half-dead', 'error'); |
||||||
|
vacuum nbtree_half_dead_pages; |
||||||
|
SELECT injection_points_detach('nbtree-leave-page-half-dead'); |
||||||
|
|
||||||
|
select * from nbtree_half_dead_pages where id > 99998 and id < 120002; |
||||||
|
|
||||||
|
-- Finish the deletion and re-check |
||||||
|
vacuum nbtree_half_dead_pages; |
||||||
|
select * from nbtree_half_dead_pages where id > 99998 and id < 120002; |
||||||
Loading…
Reference in new issue