From 0504406d44fb810db1bd1a927d4a34ddd07f2876 Mon Sep 17 00:00:00 2001 From: Bharath Rupireddy Date: Tue, 8 Sep 2026 15:47:01 +0000 Subject: [PATCH v5 1/2] Restrict REPACK (CONCURRENTLY) on user catalog tables. REPACK (CONCURRENTLY) is not an MVCC-safe operation; it doesn't preserve the visibility information, which logical decoding needs because it reads user catalog tables under a historic snapshot. Disallow REPACK (CONCURRENTLY) on user catalog tables. Removing this check requires making it MVCC-safe and logical rewrite mappings. Backpatch to v19, where REPACK (CONCURRENTLY) was introduced. Reported-by: Nathan Bossart Author: Bharath Rupireddy Reviewed-by: Antonin Houska Reviewed-by: Masahiko Sawada Reviewed-by: Alvaro Herrera Discussion: https://postgr.es/m/apBIFWzHYOaG0auN%40nathan Backpatch-through: 19 --- contrib/test_decoding/expected/repack.out | 6 ++++++ contrib/test_decoding/sql/repack.sql | 5 +++++ doc/src/sgml/ref/repack.sgml | 8 ++++++++ src/backend/commands/repack.c | 13 +++++++++++++ 4 files changed, 32 insertions(+) diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out index 5ddc63238c5..ce2cadfa222 100644 --- a/contrib/test_decoding/expected/repack.out +++ b/contrib/test_decoding/expected/repack.out @@ -61,6 +61,12 @@ HINT: Consider running the command on individual partitions. REPACK (CONCURRENTLY) pg_class; ERROR: cannot execute REPACK (CONCURRENTLY) on relation "pg_class" HINT: REPACK (CONCURRENTLY) is not supported for catalog relations. +-- 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 diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql index f461f5479f4..eb891009baf 100644 --- a/contrib/test_decoding/sql/repack.sql +++ b/contrib/test_decoding/sql/repack.sql @@ -42,6 +42,11 @@ REPACK (CONCURRENTLY) clstrpart; -- Disallowed in catalogs REPACK (CONCURRENTLY) pg_class; +-- 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; +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 diff --git a/doc/src/sgml/ref/repack.sgml b/doc/src/sgml/ref/repack.sgml index d9c7c9e6b95..d40740738f1 100644 --- a/doc/src/sgml/ref/repack.sgml +++ b/doc/src/sgml/ref/repack.sgml @@ -285,6 +285,14 @@ REPACK [ ( option [, ...] ) ] USING + + + The table is declared as a catalog table using the + user_catalog_table + storage parameter. + + + REPACK is executed inside a transaction block. diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 89aa038d23d..086bef834ec 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -897,6 +897,19 @@ check_concurrent_repack_requirements(Relation rel, Oid *ident_idx_p) errhint("%s is not supported for catalog relations.", "REPACK (CONCURRENTLY)")); + /* + * REPACK (CONCURRENTLY) is not MVCC-safe; it doesn't preserve visibility + * information, which logical decoding needs because it reads user catalog + * tables under a historic snapshot. Removing this check requires making + * it MVCC-safe and logical rewrite mappings. + */ + if (RelationIsUsedAsCatalogTable(rel)) + ereport(ERROR, + errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot execute %s on relation \"%s\"", + "REPACK (CONCURRENTLY)", RelationGetRelationName(rel)), + errdetail("This operation is not supported for user catalog tables.")); + /* * reorderbuffer.c does not seem to handle processing of TOAST relation * alone. -- 2.47.3