diff options
-rw-r--r-- | src/backend/utils/cache/catcache.c | 9 | ||||
-rw-r--r-- | src/backend/utils/cache/relcache.c | 10 |
2 files changed, 19 insertions, 0 deletions
diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c index d0e364e00de..2241cb91f29 100644 --- a/src/backend/utils/cache/catcache.c +++ b/src/backend/utils/cache/catcache.c @@ -26,6 +26,7 @@ #ifdef CATCACHE_STATS #include "storage/ipc.h" /* for on_proc_exit */ #endif +#include "storage/lmgr.h" #include "utils/builtins.h" #include "utils/fmgroids.h" #include "utils/inval.h" @@ -967,8 +968,16 @@ InitCatCachePhase2(CatCache *cache, bool touch_index) { Relation idesc; + /* + * We must lock the underlying catalog before opening the index to + * avoid deadlock, since index_open could possibly result in reading + * this same catalog, and if anyone else is exclusive-locking this + * catalog and index they'll be doing it in that order. + */ + LockRelationOid(cache->cc_reloid, AccessShareLock); idesc = index_open(cache->cc_indexoid, AccessShareLock); index_close(idesc, AccessShareLock); + UnlockRelationOid(cache->cc_reloid, AccessShareLock); } } diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index 90464fd0663..274b48c8951 100644 --- a/src/backend/utils/cache/relcache.c +++ b/src/backend/utils/cache/relcache.c @@ -1651,6 +1651,12 @@ RelationClose(Relation relation) * We assume that at the time we are called, we have at least AccessShareLock * on the target index. (Note: in the calls from RelationClearRelation, * this is legitimate because we know the rel has positive refcount.) + * + * If the target index is an index on pg_class or pg_index, we'd better have + * previously gotten at least AccessShareLock on its underlying catalog, + * else we are at risk of deadlock against someone trying to exclusive-lock + * the heap and index in that order. This is ensured in current usage by + * only applying this to indexes being opened or having positive refcount. */ static void RelationReloadIndexInfo(Relation relation) @@ -3611,6 +3617,10 @@ RelationGetIndexPredicate(Relation relation) * Attribute numbers are offset by FirstLowInvalidHeapAttributeNumber so that * we can include system attributes (e.g., OID) in the bitmap representation. * + * Caller had better hold at least RowExclusiveLock on the target relation + * to ensure that it has a stable set of indexes. This also makes it safe + * (deadlock-free) for us to take locks on the relation's indexes. + * * The returned result is palloc'd in the caller's memory context and should * be bms_free'd when not needed anymore. */ |