• Andres Freund's avatar
    Fix potential assertion failure when reindexing a pg_class index. · 3dbb317d
    Andres Freund authored
    When reindexing individual indexes on pg_class it was possible to
    either trigger an assertion failure:
    TRAP: FailedAssertion("!(!ReindexIsProcessingIndex(((index)->rd_id)))
    
    That's because reindex_index() called SetReindexProcessing() - which
    enables an asserts ensuring no index insertions happen into the index
    - before calling RelationSetNewRelfilenode(). That not correct for
    indexes on pg_class, because RelationSetNewRelfilenode() updates the
    relevant pg_class row, which needs to update the indexes.
    
    The are two reasons this wasn't noticed earlier. Firstly the bug
    doesn't trigger when reindexing all of pg_class, as reindex_relation
    has code "hiding" all yet-to-be-reindexed indexes. Secondly, the bug
    only triggers when the the update to pg_class doesn't turn out to be a
    HOT update - otherwise there's no index insertion to trigger the
    bug. Most of the time there's enough space, making this bug hard to
    trigger.
    
    To fix, move RelationSetNewRelfilenode() to before the
    SetReindexProcessing() (and, together with some other code, to outside
    of the PG_TRY()).
    
    To make sure the error checking intended by SetReindexProcessing() is
    more robust, modify CatalogIndexInsert() to check
    ReindexIsProcessingIndex() even when the update is a HOT update.
    
    Also add a few regression tests for REINDEXing of system catalogs.
    
    The last two improvements would have prevented some of the issues
    fixed in 5c156060 from being introduced in the first place.
    
    Reported-By: Michael Paquier
    Diagnosed-By: Tom Lane and Andres Freund
    Author: Andres Freund
    Reviewed-By: Tom Lane
    Discussion: https://postgr.es/m/20190418011430.GA19133@paquier.xyz
    Backpatch: 9.4-, the bug is present in all branches
    3dbb317d
rewrite.out 6.81 KB