mirror of
https://github.com/postgres/postgres.git
synced 2025-07-18 17:42:25 +03:00
Fix wrong validation of top-parent pointer during page deletion in Btree.
After introducing usage of t_tid of inner or page high key for storing number of attributes of tuple, validation of tuple's ItemPointer with ItemPointerIsValid becomes incorrect, it's need to validate only blocknumber of ItemPointer. Missing this causes a incorrect page deletion, fix that. Test is added. BTW, current contrib/amcheck doesn't fail on index corrupted by this way. Also introduce BTreeTupleGetTopParent/BTreeTupleSetTopParent macroses to improve code readability and to avoid possible confusion with page high key: high key is used to store top-parent link for branch to remove. Bug found by Michael Paquier, but bug doesn't exist in previous versions because t_tid was set to P_HIKEY. Author: Teodor Sigaev Reviewer: Peter Geoghegan Discussion: https://www.postgresql.org/message-id/flat/20180419052436.GA16000%40paquier.xyz
This commit is contained in:
@ -3052,6 +3052,16 @@ explain (costs off)
|
||||
Filter: (NOT b)
|
||||
(4 rows)
|
||||
|
||||
--
|
||||
-- Test for multilevel page deletion
|
||||
--
|
||||
CREATE TABLE delete_test_table (a bigint, b bigint, c bigint, d bigint);
|
||||
INSERT INTO delete_test_table SELECT i, 1, 2, 3 FROM generate_series(1,80000) i;
|
||||
ALTER TABLE delete_test_table ADD PRIMARY KEY (a,b,c,d);
|
||||
DELETE FROM delete_test_table WHERE a > 40000;
|
||||
VACUUM delete_test_table;
|
||||
DELETE FROM delete_test_table WHERE a > 10;
|
||||
VACUUM delete_test_table;
|
||||
--
|
||||
-- REINDEX (VERBOSE)
|
||||
--
|
||||
|
@ -38,6 +38,7 @@ d_star|f
|
||||
date_tbl|f
|
||||
default_tbl|f
|
||||
defaultexpr_tbl|f
|
||||
delete_test_table|t
|
||||
dept|f
|
||||
dupindexcols|t
|
||||
e_star|f
|
||||
|
@ -1061,6 +1061,17 @@ explain (costs off)
|
||||
explain (costs off)
|
||||
select * from boolindex where not b order by i limit 10;
|
||||
|
||||
--
|
||||
-- Test for multilevel page deletion
|
||||
--
|
||||
CREATE TABLE delete_test_table (a bigint, b bigint, c bigint, d bigint);
|
||||
INSERT INTO delete_test_table SELECT i, 1, 2, 3 FROM generate_series(1,80000) i;
|
||||
ALTER TABLE delete_test_table ADD PRIMARY KEY (a,b,c,d);
|
||||
DELETE FROM delete_test_table WHERE a > 40000;
|
||||
VACUUM delete_test_table;
|
||||
DELETE FROM delete_test_table WHERE a > 10;
|
||||
VACUUM delete_test_table;
|
||||
|
||||
--
|
||||
-- REINDEX (VERBOSE)
|
||||
--
|
||||
|
Reference in New Issue
Block a user