• Tom Lane's avatar
    Fix reindexing of pg_class indexes some more. · f912d7de
    Tom Lane authored
    Commits 3dbb317d et al failed under CLOBBER_CACHE_ALWAYS testing.
    Investigation showed that to reindex pg_class_oid_index, we must
    suppress accesses to the index (via SetReindexProcessing) before we call
    RelationSetNewRelfilenode, or at least before we do CommandCounterIncrement
    therein; otherwise, relcache reloads happening within the CCI may try to
    fetch pg_class rows using the index's new relfilenode value, which is as
    yet an empty file.
    
    Of course, the point of 3dbb317d was that that ordering didn't work
    either, because then RelationSetNewRelfilenode's own update of the index's
    pg_class row cannot access the index, should it need to.
    
    There are various ways we might have got around that, but Andres Freund
    came up with a brilliant solution: for a mapped index, we can really just
    skip the pg_class update altogether.  The only fields it was actually
    changing were relpages etc, but it was just setting them to zeroes which
    is useless make-work.  (Correct new values will be installed at the end
    of index build.)  All pg_class indexes are mapped and probably always will
    be, so this eliminates the problem by removing work rather than adding it,
    always a pleasant outcome.  Having taught RelationSetNewRelfilenode to do
    it that way, we can revert the code reordering in reindex_index.  (But
    I left the moved setup code where it was; there seems no reason why it
    has to run without use of the old index.  If you're trying to fix a
    busted pg_class index, you'll have had to disable system index use
    altogether to get this far.)
    
    Moreover, this means we don't need RelationSetIndexList at all, because
    reindex_relation's hacking to make "REINDEX TABLE pg_class" work is
    likewise now unnecessary.  We'll leave that code in place in the back
    branches, but a follow-on patch will remove it in HEAD.
    
    In passing, do some minor cleanup for commit 5c156060 (in HEAD only),
    notably removing a duplicate newrnode assignment.
    
    Patch by me, using a core idea due to Andres Freund.  Back-patch to all
    supported branches, as 3dbb317d was.
    
    Discussion: https://postgr.es/m/28926.1556664156@sss.pgh.pa.us
    f912d7de
relcache.c 190 KB