postgres.git / summary / log / commit / refs

commit    09620ea09121b66e9372e8e9244d8bb6b19b89d7
Author:   Michael Paquier <michael@paquier.xyz>
Date:     Fri Sep 27 00:40:09 2024 +0000
First released in: 18.0, 12.21, 13.17, 14.14, 15.9, 16.5, 17.1

    Fix incorrect memory access in VACUUM FULL with invalid toast indexes
    
    An invalid toast index is skipped in reindex_relation().  These would be
    remnants of a failed REINDEX CONCURRENTLY and they should never been
    rebuilt as there can only be one valid toast index at a time.
    
    REINDEX_REL_SUPPRESS_INDEX_USE, used by CLUSTER and VACUUM FULL, needs
    to maintain a list of the indexes being processed.  The list of indexes
    is retrieved from the relation cache, and includes invalid indexes.  The
    code has missed that invalid toast indexes are ignored in
    reindex_relation() as this leads to a hard failure in reindex_index(),
    and they were left in the reindex pending list, making the list
    inconsistent when rechecked.  The incorrect memory access was happening
    when scanning pg_class for the refresh of pg_database.datfrozenxid, when
    doing a scan of pg_class.
    
    This issue exists since REINDEX CONCURRENTLY exists, where invalid toast
    indexes can exist, so backpatch all the way down.
    
    Reported-by: Alexander Lakhin
    Author: Tender Wang
    Discussion: https://postgr.es/m/18630-9aed99c38830657d@postgresql.org
    Backpatch-through: 12


src/backend/catalog/index.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index cecee93ad8e..6084dfa97cb 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -4010,6 +4010,14 @@ reindex_relation(const ReindexStmt *stmt, Oid relid, int flags, errmsg("cannot reindex invalid index \"%s.%s\" on TOAST table, skipping", get_namespace_name(indexNamespaceId), get_rel_name(indexOid)))); + + /* + * Remove this invalid toast index from the reindex pending list, + * as it is skipped here due to the hard failure that would happen + * in reindex_index(), should we try to process it. + */ + if (flags & REINDEX_REL_SUPPRESS_INDEX_USE) + RemoveReindexPending(indexOid); continue; } [parent: f762d99c8783]