aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/utils/cache/catcache.c9
-rw-r--r--src/backend/utils/cache/relcache.c6
2 files changed, 15 insertions, 0 deletions
diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index a8658116283..0b27bc034c0 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -24,6 +24,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/memutils.h"
@@ -1009,8 +1010,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 f6853899b3c..59648a5ddec 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1541,6 +1541,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
RelationReloadClassinfo(Relation relation)