1
0
mirror of https://github.com/postgres/postgres.git synced 2026-10-23 13:29:09 +03:00
Files
postgres/contrib/test_decoding/expected/repack.out
Álvaro Herrera 0c5d626961 Fail REPACK in presence of !indisready indexes
Like VACUUM FULL, non-concurrent REPACK would try to rebuild such
indexes, which can sometimes succeed.  Concurrent REPACK would however
fail.  The inconsistency is not good, so make them both throw an error
quickly to force the user to make a decision on those indexes (most
likely, drop them).

Author: Álvaro Herrera <alvherre@kurilemu.de>
Reported-by: Zsolt Parragi <zsolt.parragi@percona.com>
Suggested-by: Kyotaro Horiguchi <horikyota.ntt@gmail.com>
Discussion: https://postgr.es/m/CAN4CZFO5A3YE0Dd-bn7eKrB20pECO3=U0wKg1z2rO=DxgWJJHQ@mail.gmail.com
2026-09-13 14:06:00 +02:00

152 lines
7.0 KiB
Plaintext

-- Test REPACK (CONCURRENTLY).
-- This test isn't strictly about logical decoding per se, but
-- REPACK (CONCURRENTLY) involves logical decoding and therefore requires
-- to be run under higher than minimal wal_level, so we can't have them in
-- the main regression test suite.
-- Ownership of partitions is checked
CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
CREATE INDEX ptnowner_i_idx ON ptnowner(i);
CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
CREATE ROLE regress_ptnowner;
CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
SET SESSION AUTHORIZATION regress_ptnowner;
ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
REPACK (CONCURRENTLY) ptnowner1;
RESET SESSION AUTHORIZATION;
ALTER TABLE ptnowner OWNER TO regress_ptnowner;
CREATE TEMP TABLE ptnowner_oldnodes AS
SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
JOIN pg_class AS c ON c.oid=tree.relid;
SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
relname | ?column?
-----------+----------
ptnowner | t
ptnowner1 | t
ptnowner2 | t
(3 rows)
DROP TABLE ptnowner;
DROP ROLE regress_ptnowner;
-- Verify that REPACK (CONCURRENTLY) doesn't lose "attmissingval" columns
CREATE TABLE rpk_missing (id int PRIMARY KEY);
INSERT INTO rpk_missing SELECT generate_series(1, 3);
ALTER TABLE rpk_missing ADD COLUMN a int DEFAULT 42;
SELECT * FROM rpk_missing;
id | a
----+----
1 | 42
2 | 42
3 | 42
(3 rows)
REPACK (CONCURRENTLY) rpk_missing;
SELECT * FROM rpk_missing;
id | a
----+----
1 | 42
2 | 42
3 | 42
(3 rows)
DROP TABLE rpk_missing;
-- Verify handling of !indisready indexes
CREATE TABLE repack_conc_invidx (i int PRIMARY KEY, j int);
INSERT INTO repack_conc_invidx VALUES (1, 0), (2, 0);
CREATE UNIQUE INDEX CONCURRENTLY repack_conc_invidx_uq ON repack_conc_invidx (j);
ERROR: could not create unique index "repack_conc_invidx_uq"
DETAIL: Key (j)=(0) is duplicated.
CREATE INDEX CONCURRENTLY repack_conc_invalid_expr ON repack_conc_invidx ((1/j));
ERROR: division by zero
REPACK repack_conc_invidx;
ERROR: cannot execute REPACK on relation "repack_conc_invidx"
DETAIL: Some invalid indexes cannot be processed correctly: "repack_conc_invidx_uq", "repack_conc_invalid_expr".
HINT: Use DROP INDEX or REINDEX.
REPACK (CONCURRENTLY) repack_conc_invidx;
ERROR: cannot execute REPACK on relation "repack_conc_invidx"
DETAIL: Some invalid indexes cannot be processed correctly: "repack_conc_invidx_uq", "repack_conc_invalid_expr".
HINT: Use DROP INDEX or REINDEX.
-- Error cases for concurrent mode
-- Doesn't like partitioned tables
CREATE TABLE clstrpart (a int) PARTITION BY RANGE (a);
REPACK (CONCURRENTLY) clstrpart;
ERROR: REPACK (CONCURRENTLY) is not supported for partitioned tables
HINT: Consider running the command on individual partitions.
-- Disallowed in catalogs
REPACK (CONCURRENTLY) pg_class;
ERROR: cannot execute REPACK (CONCURRENTLY) on relation "pg_class"
DETAIL: This operation is not supported for system catalogs.
-- Doesn't support tables used as catalog tables
CREATE TABLE repack_conc_user_catalog (i int) WITH (user_catalog_table = true);
REPACK (CONCURRENTLY) repack_conc_user_catalog;
ERROR: cannot execute REPACK (CONCURRENTLY) on relation "repack_conc_user_catalog"
DETAIL: This operation is not supported for user catalog tables.
DROP TABLE repack_conc_user_catalog;
-- Doesn't support TOAST tables directly
CREATE TABLE repack_conc_toast (t text);
SELECT reltoastrelid::regclass AS toast_rel
FROM pg_class WHERE oid = 'repack_conc_toast'::regclass \gset
\set VERBOSITY sqlstate
REPACK (CONCURRENTLY) :toast_rel;
ERROR: 0A000
\set VERBOSITY default
DROP TABLE repack_conc_toast;
-- Only support permanent tables, temp and unlogged tables are not supported
CREATE TEMP TABLE repack_conc_temp (i int PRIMARY KEY);
REPACK (CONCURRENTLY) repack_conc_temp;
ERROR: cannot execute REPACK (CONCURRENTLY) on relation "repack_conc_temp"
DETAIL: This operation is only supported for permanent relations.
DROP TABLE repack_conc_temp;
CREATE UNLOGGED TABLE repack_conc_unlogged (i int PRIMARY KEY);
REPACK (CONCURRENTLY) repack_conc_unlogged;
ERROR: cannot execute REPACK (CONCURRENTLY) on relation "repack_conc_unlogged"
DETAIL: This operation is only supported for permanent relations.
DROP TABLE repack_conc_unlogged;
-- Doesn't support materialized views
CREATE MATERIALIZED VIEW repack_conc_matview AS SELECT 1 AS i;
REPACK (CONCURRENTLY) repack_conc_matview;
ERROR: cannot execute REPACK (CONCURRENTLY) on relation "repack_conc_matview"
DETAIL: This operation is not supported for materialized views.
DROP MATERIALIZED VIEW repack_conc_matview;
-- Doesn't support tables with REPLICA IDENTITY NOTHING, even if they have a primary key
CREATE TABLE repack_conc_replident (i int PRIMARY KEY);
ALTER TABLE repack_conc_replident REPLICA IDENTITY NOTHING;
REPACK (CONCURRENTLY) repack_conc_replident;
ERROR: cannot execute REPACK (CONCURRENTLY) on relation "repack_conc_replident"
DETAIL: This operation does not support tables with REPLICA IDENTITY NOTHING.
-- Doesn't support tables without a primary key or replica identity index
ALTER TABLE repack_conc_replident DROP CONSTRAINT repack_conc_replident_pkey;
ALTER TABLE repack_conc_replident REPLICA IDENTITY DEFAULT;
REPACK (CONCURRENTLY) repack_conc_replident;
ERROR: cannot execute REPACK (CONCURRENTLY) on relation "repack_conc_replident"
DETAIL: Relation "repack_conc_replident" has no identity index.
-- Doesn't support tables with deferrable primary keys
ALTER TABLE repack_conc_replident ADD PRIMARY KEY (i) DEFERRABLE;
REPACK (CONCURRENTLY) repack_conc_replident;
ERROR: cannot execute REPACK (CONCURRENTLY) on relation "repack_conc_replident"
DETAIL: This operation does not support deferrable primary keys.
HINT: Use ALTER TABLE ... REPLICA IDENTITY USING INDEX to designate another index as replica identity.
-- Doesn't support tables whose replica identity indexes were dropped, even
-- if a workable primary key is present.
ALTER TABLE repack_conc_replident DROP CONSTRAINT repack_conc_replident_pkey,
ADD PRIMARY KEY (i);
CREATE UNIQUE INDEX replidx ON repack_conc_replident (i);
ALTER TABLE repack_conc_replident REPLICA IDENTITY USING INDEX replidx;
DROP INDEX replidx;
REPACK (CONCURRENTLY) repack_conc_replident;
ERROR: cannot execute REPACK (CONCURRENTLY) on relation "repack_conc_replident"
DETAIL: Relation "repack_conc_replident" has no identity index.
-- clean up
DROP TABLE repack_conc_replident, clstrpart;
-- verify that the pgrepack plugin cannot be called directly
CREATE TABLE repack_plugin (a int);
SELECT * FROM pg_create_logical_replication_slot('s_repack', 'pgrepack');
ERROR: unsupported use of logical decoding plugin "pgrepack"
DETAIL: This plugin can only be used by REPACK (CONCURRENTLY).
INSERT INTO repack_plugin VALUES (1);
SELECT * FROM pg_logical_slot_get_binary_changes('s_repack', NULL, NULL);
ERROR: replication slot "s_repack" does not exist
SELECT pg_drop_replication_slot('s_repack');
ERROR: replication slot "s_repack" does not exist