postgres.git / summary / log / commit / refs

commit    78142821dfd42a7ca1010811ce77ff7b96218741
Author:   Álvaro Herrera <alvherre@kurilemu.de>
Date:     Tue Sep 15 13:40:59 2026 +0000

    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 <zhong950419@gmail.com>
    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 [ ( <replaceable class="parameter">option</replaceable> [, ...] ) ] USING on the table. </para> + <para> + <command>REPACK</command> refuses to process a table on which an invalid + index exists. Such indexes must be dropped or reindexed by the user ahead + of time. + </para> + <para> While <command>REPACK</command> is running, the <xref linkend="guc-search-path"/> is temporarily changed to <literal>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 [parent: ddce1da5b1b1]