• T
    Fix RelationCacheInitializePhase2 (Phase3, in HEAD) to cope with the · 8b720b57
    Tom Lane 提交于
    possibility of shared-inval messages causing a relcache flush while it tries
    to fill in missing data in preloaded relcache entries.  There are actually
    two distinct failure modes here:
    
    1. The flush could delete the next-to-be-processed cache entry, causing
    the subsequent hash_seq_search calls to go off into the weeds.  This is
    the problem reported by Michael Brown, and I believe it also accounts
    for bug #5074.  The simplest fix is to restart the hashtable scan after
    we've read any new data from the catalogs.  It appears that pre-8.4
    branches have not suffered from this failure, because by chance there were
    no other catalogs sharing the same hash chains with the catalogs that
    RelationCacheInitializePhase2 had work to do for.  However that's obviously
    pretty fragile, and it seems possible that derivative versions with
    additional system catalogs might be vulnerable, so I'm back-patching this
    part of the fix anyway.
    
    2. The flush could delete the *current* cache entry, in which case the
    pointer to the newly-loaded data would end up being stored into an
    already-deleted Relation struct.  As long as it was still deleted, the only
    consequence would be some leaked space in CacheMemoryContext.  But it seems
    possible that the Relation struct could already have been recycled, in
    which case this represents a hard-to-reproduce clobber of cached data
    structures, with unforeseeable consequences.  The fix here is to pin the
    entry while we work on it.
    
    In passing, also change RelationCacheInitializePhase2 to Assert that
    formrdesc() set up the relation's cached TupleDesc (rd_att) with the
    correct type OID and hasoids values.  This is more appropriate than
    silently updating the values, because the original tupdesc might already
    have been copied into the catcache.  However this part of the patch is
    not in HEAD because it fails due to some questionable recent changes in
    formrdesc :-(.  That will be cleaned up in a subsequent patch.
    8b720b57
relcache.c 119.3 KB