From 78142821dfd42a7ca1010811ce77ff7b96218741 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Herrera?= Date: Tue, 15 Sep 2026 15:40:59 +0200 Subject: [PATCH] Fail REPACK in presence of invalid indexes, take 2 Commit 0c5d6269614e was confused about which indexes are potentially problematic to rebuild: we thought only !indisready indexes could fail to rebuild, and thus would attempt to rebuild !indisvalid ones that are "ready" (that is, being maintained by DML but not yet completed). However, that's wrong, because it could be that the validation phase of such an index failed or was interrupted partway through. So, have REPACK throw an error with all !indisvalid indexes, not just those !indisready. (!indisready implies !indisvalid, so this is an expansion of what happened with the previous commit.) Reported-by: shihao zhong Backpatch-through: 19 Discussion: https://postgr.es/m/CAGRkXqRA4YetT8Nu3+1-45+ffTwi2bd1d1eDFME39Y9OPRMytQ@mail.gmail.com --- doc/src/sgml/ref/repack.sgml | 6 ++++++ src/backend/commands/repack.c | 15 ++++++++------- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/doc/src/sgml/ref/repack.sgml b/doc/src/sgml/ref/repack.sgml index 3ba037848f6..346cba89c90 100644 --- a/doc/src/sgml/ref/repack.sgml +++ b/doc/src/sgml/ref/repack.sgml @@ -384,6 +384,12 @@ REPACK [ ( option [, ...] ) ] USING on the table. + + REPACK refuses to process a table on which an invalid + index exists. Such indexes must be dropped or reindexed by the user ahead + of time. + + While REPACK is running, the is temporarily changed to pg_catalog, diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index e0fc96558d9..3e972f2cc14 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -886,13 +886,15 @@ mark_index_clustered(Relation rel, Oid indexOid, bool is_internal) /* * check_index_requirements: verify index state on relation being processed * - * Throw an error if any !indisready indexes are found. + * Throw an error if any incompletely-built indexes are found. * * Indexes that are not ready for inserts, such as ones left behind by failed - * CREATE INDEX CONCURRENTLY, are not maintained by DML. In some cases they - * may fail to build altogether. Throwing an error here forces the user to - * take action on these indexes separately from the table reconstruction, - * which prevents perpetuating them for no reason. + * CREATE INDEX CONCURRENTLY, are not maintained by DML. Indexes that aren't + * marked valid could have been in the middle of validation when their build + * failed, and thus it's not certain that they could be built. In both cases, + * attempting to rebuild may fail altogether. Throwing an error here forces + * the user to take action on these indexes separately from the table + * reconstruction, which prevents perpetuating them for no reason. */ static void check_index_requirements(Relation rel, RepackCommand cmd) @@ -920,9 +922,8 @@ check_index_requirements(Relation rel, RepackCommand cmd) { Form_pg_index index = (Form_pg_index) GETSTRUCT(htup); - if (!index->indisready) + if (!index->indisvalid) { - Assert(!index->indisvalid); if (num_invalid_idxs == 0) appendStringInfo(&dest, _("\"%s\""), get_rel_name(index->indexrelid)); else