mirror of
https://github.com/postgres/postgres.git
synced 2025-07-07 00:36:50 +03:00
Fix REINDEX CONCURRENTLY of partitions
In case of a partition index, when swapping the old and new index, we also need to attach the new index as a partition and detach the old one. Also, to handle partition indexes, we not only need to change dependencies referencing the index, but also dependencies of the index referencing something else. The previous code did this only specifically for a constraint, but we also need to do this for partitioned indexes. So instead write a generic function that does it for all dependencies. Author: Michael Paquier <michael@paquier.xyz> Author: Peter Eisentraut <peter.eisentraut@2ndquadrant.com> Discussion: https://www.postgresql.org/message-id/flat/DF4PR8401MB11964EDB77C860078C343BEBEE5A0%40DF4PR8401MB1196.NAMPRD84.PROD.OUTLOOK.COM#154df1fedb735190a773481765f7b874
This commit is contained in:
@ -2001,6 +2001,91 @@ SELECT obj_description('testcomment_idx1'::regclass, 'pg_class');
|
||||
(1 row)
|
||||
|
||||
DROP TABLE testcomment;
|
||||
-- Partitions
|
||||
-- Create some partitioned tables
|
||||
CREATE TABLE concur_reindex_part (c1 int, c2 int) PARTITION BY RANGE (c1);
|
||||
CREATE TABLE concur_reindex_part_0 PARTITION OF concur_reindex_part
|
||||
FOR VALUES FROM (0) TO (10) PARTITION BY list (c2);
|
||||
CREATE TABLE concur_reindex_part_0_1 PARTITION OF concur_reindex_part_0
|
||||
FOR VALUES IN (1);
|
||||
CREATE TABLE concur_reindex_part_0_2 PARTITION OF concur_reindex_part_0
|
||||
FOR VALUES IN (2);
|
||||
-- This partitioned table will have no partitions.
|
||||
CREATE TABLE concur_reindex_part_10 PARTITION OF concur_reindex_part
|
||||
FOR VALUES FROM (10) TO (20) PARTITION BY list (c2);
|
||||
-- Create some partitioned indexes
|
||||
CREATE INDEX concur_reindex_part_index ON ONLY concur_reindex_part (c1);
|
||||
CREATE INDEX concur_reindex_part_index_0 ON ONLY concur_reindex_part_0 (c1);
|
||||
ALTER INDEX concur_reindex_part_index ATTACH PARTITION concur_reindex_part_index_0;
|
||||
-- This partitioned index will have no partitions.
|
||||
CREATE INDEX concur_reindex_part_index_10 ON ONLY concur_reindex_part_10 (c1);
|
||||
ALTER INDEX concur_reindex_part_index ATTACH PARTITION concur_reindex_part_index_10;
|
||||
CREATE INDEX concur_reindex_part_index_0_1 ON ONLY concur_reindex_part_0_1 (c1);
|
||||
ALTER INDEX concur_reindex_part_index_0 ATTACH PARTITION concur_reindex_part_index_0_1;
|
||||
CREATE INDEX concur_reindex_part_index_0_2 ON ONLY concur_reindex_part_0_2 (c1);
|
||||
ALTER INDEX concur_reindex_part_index_0 ATTACH PARTITION concur_reindex_part_index_0_2;
|
||||
SELECT relid, parentrelid, level FROM pg_partition_tree('concur_reindex_part_index')
|
||||
ORDER BY relid, level;
|
||||
relid | parentrelid | level
|
||||
-------------------------------+-----------------------------+-------
|
||||
concur_reindex_part_index | | 0
|
||||
concur_reindex_part_index_0 | concur_reindex_part_index | 1
|
||||
concur_reindex_part_index_10 | concur_reindex_part_index | 1
|
||||
concur_reindex_part_index_0_1 | concur_reindex_part_index_0 | 2
|
||||
concur_reindex_part_index_0_2 | concur_reindex_part_index_0 | 2
|
||||
(5 rows)
|
||||
|
||||
-- REINDEX fails for partitioned indexes
|
||||
REINDEX INDEX concur_reindex_part_index_10;
|
||||
ERROR: REINDEX is not yet implemented for partitioned indexes
|
||||
REINDEX INDEX CONCURRENTLY concur_reindex_part_index_10;
|
||||
ERROR: REINDEX is not yet implemented for partitioned indexes
|
||||
-- REINDEX is a no-op for partitioned tables
|
||||
REINDEX TABLE concur_reindex_part_10;
|
||||
WARNING: REINDEX of partitioned tables is not yet implemented, skipping "concur_reindex_part_10"
|
||||
NOTICE: table "concur_reindex_part_10" has no indexes
|
||||
REINDEX TABLE CONCURRENTLY concur_reindex_part_10;
|
||||
WARNING: REINDEX of partitioned tables is not yet implemented, skipping "concur_reindex_part_10"
|
||||
NOTICE: table "concur_reindex_part_10" has no indexes
|
||||
SELECT relid, parentrelid, level FROM pg_partition_tree('concur_reindex_part_index')
|
||||
ORDER BY relid, level;
|
||||
relid | parentrelid | level
|
||||
-------------------------------+-----------------------------+-------
|
||||
concur_reindex_part_index | | 0
|
||||
concur_reindex_part_index_0 | concur_reindex_part_index | 1
|
||||
concur_reindex_part_index_10 | concur_reindex_part_index | 1
|
||||
concur_reindex_part_index_0_1 | concur_reindex_part_index_0 | 2
|
||||
concur_reindex_part_index_0_2 | concur_reindex_part_index_0 | 2
|
||||
(5 rows)
|
||||
|
||||
-- REINDEX should preserve dependencies of partition tree.
|
||||
REINDEX INDEX CONCURRENTLY concur_reindex_part_index_0_1;
|
||||
REINDEX INDEX CONCURRENTLY concur_reindex_part_index_0_2;
|
||||
SELECT relid, parentrelid, level FROM pg_partition_tree('concur_reindex_part_index')
|
||||
ORDER BY relid, level;
|
||||
relid | parentrelid | level
|
||||
-------------------------------+-----------------------------+-------
|
||||
concur_reindex_part_index | | 0
|
||||
concur_reindex_part_index_0 | concur_reindex_part_index | 1
|
||||
concur_reindex_part_index_10 | concur_reindex_part_index | 1
|
||||
concur_reindex_part_index_0_1 | concur_reindex_part_index_0 | 2
|
||||
concur_reindex_part_index_0_2 | concur_reindex_part_index_0 | 2
|
||||
(5 rows)
|
||||
|
||||
REINDEX TABLE CONCURRENTLY concur_reindex_part_0_1;
|
||||
REINDEX TABLE CONCURRENTLY concur_reindex_part_0_2;
|
||||
SELECT relid, parentrelid, level FROM pg_partition_tree('concur_reindex_part_index')
|
||||
ORDER BY relid, level;
|
||||
relid | parentrelid | level
|
||||
-------------------------------+-----------------------------+-------
|
||||
concur_reindex_part_index | | 0
|
||||
concur_reindex_part_index_0 | concur_reindex_part_index | 1
|
||||
concur_reindex_part_index_10 | concur_reindex_part_index | 1
|
||||
concur_reindex_part_index_0_1 | concur_reindex_part_index_0 | 2
|
||||
concur_reindex_part_index_0_2 | concur_reindex_part_index_0 | 2
|
||||
(5 rows)
|
||||
|
||||
DROP TABLE concur_reindex_part;
|
||||
-- Check errors
|
||||
-- Cannot run inside a transaction block
|
||||
BEGIN;
|
||||
|
@ -789,6 +789,49 @@ SELECT obj_description('testcomment_idx1'::regclass, 'pg_class');
|
||||
REINDEX TABLE CONCURRENTLY testcomment ;
|
||||
SELECT obj_description('testcomment_idx1'::regclass, 'pg_class');
|
||||
DROP TABLE testcomment;
|
||||
-- Partitions
|
||||
-- Create some partitioned tables
|
||||
CREATE TABLE concur_reindex_part (c1 int, c2 int) PARTITION BY RANGE (c1);
|
||||
CREATE TABLE concur_reindex_part_0 PARTITION OF concur_reindex_part
|
||||
FOR VALUES FROM (0) TO (10) PARTITION BY list (c2);
|
||||
CREATE TABLE concur_reindex_part_0_1 PARTITION OF concur_reindex_part_0
|
||||
FOR VALUES IN (1);
|
||||
CREATE TABLE concur_reindex_part_0_2 PARTITION OF concur_reindex_part_0
|
||||
FOR VALUES IN (2);
|
||||
-- This partitioned table will have no partitions.
|
||||
CREATE TABLE concur_reindex_part_10 PARTITION OF concur_reindex_part
|
||||
FOR VALUES FROM (10) TO (20) PARTITION BY list (c2);
|
||||
-- Create some partitioned indexes
|
||||
CREATE INDEX concur_reindex_part_index ON ONLY concur_reindex_part (c1);
|
||||
CREATE INDEX concur_reindex_part_index_0 ON ONLY concur_reindex_part_0 (c1);
|
||||
ALTER INDEX concur_reindex_part_index ATTACH PARTITION concur_reindex_part_index_0;
|
||||
-- This partitioned index will have no partitions.
|
||||
CREATE INDEX concur_reindex_part_index_10 ON ONLY concur_reindex_part_10 (c1);
|
||||
ALTER INDEX concur_reindex_part_index ATTACH PARTITION concur_reindex_part_index_10;
|
||||
CREATE INDEX concur_reindex_part_index_0_1 ON ONLY concur_reindex_part_0_1 (c1);
|
||||
ALTER INDEX concur_reindex_part_index_0 ATTACH PARTITION concur_reindex_part_index_0_1;
|
||||
CREATE INDEX concur_reindex_part_index_0_2 ON ONLY concur_reindex_part_0_2 (c1);
|
||||
ALTER INDEX concur_reindex_part_index_0 ATTACH PARTITION concur_reindex_part_index_0_2;
|
||||
SELECT relid, parentrelid, level FROM pg_partition_tree('concur_reindex_part_index')
|
||||
ORDER BY relid, level;
|
||||
-- REINDEX fails for partitioned indexes
|
||||
REINDEX INDEX concur_reindex_part_index_10;
|
||||
REINDEX INDEX CONCURRENTLY concur_reindex_part_index_10;
|
||||
-- REINDEX is a no-op for partitioned tables
|
||||
REINDEX TABLE concur_reindex_part_10;
|
||||
REINDEX TABLE CONCURRENTLY concur_reindex_part_10;
|
||||
SELECT relid, parentrelid, level FROM pg_partition_tree('concur_reindex_part_index')
|
||||
ORDER BY relid, level;
|
||||
-- REINDEX should preserve dependencies of partition tree.
|
||||
REINDEX INDEX CONCURRENTLY concur_reindex_part_index_0_1;
|
||||
REINDEX INDEX CONCURRENTLY concur_reindex_part_index_0_2;
|
||||
SELECT relid, parentrelid, level FROM pg_partition_tree('concur_reindex_part_index')
|
||||
ORDER BY relid, level;
|
||||
REINDEX TABLE CONCURRENTLY concur_reindex_part_0_1;
|
||||
REINDEX TABLE CONCURRENTLY concur_reindex_part_0_2;
|
||||
SELECT relid, parentrelid, level FROM pg_partition_tree('concur_reindex_part_index')
|
||||
ORDER BY relid, level;
|
||||
DROP TABLE concur_reindex_part;
|
||||
|
||||
-- Check errors
|
||||
-- Cannot run inside a transaction block
|
||||
|
Reference in New Issue
Block a user