diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 16a1c08909ab74c365b69743d2ddd0316c1ee0ba..30a32d17f9a1adba591a934c477e11940764e0dc 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.299 2010/01/12 18:12:18 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.300 2010/01/13 23:07:08 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -46,9 +46,11 @@
 #include "catalog/pg_database.h"
 #include "catalog/pg_namespace.h"
 #include "catalog/pg_opclass.h"
+#include "catalog/pg_operator.h"
 #include "catalog/pg_proc.h"
 #include "catalog/pg_rewrite.h"
 #include "catalog/pg_tablespace.h"
+#include "catalog/pg_trigger.h"
 #include "catalog/pg_type.h"
 #include "catalog/schemapg.h"
 #include "commands/trigger.h"
@@ -217,7 +219,7 @@ static void RelationParseRelOptions(Relation relation, HeapTuple tuple);
 static void RelationBuildTupleDesc(Relation relation);
 static Relation RelationBuildDesc(Oid targetRelId, bool insertIt);
 static void RelationInitPhysicalAddr(Relation relation);
-static void load_critical_index(Oid indexoid);
+static void load_critical_index(Oid indexoid, Oid heapoid);
 static TupleDesc GetPgClassDescriptor(void);
 static TupleDesc GetPgIndexDescriptor(void);
 static void AttrDefaultFetch(Relation relation);
@@ -2719,15 +2721,24 @@ RelationCacheInitializePhase3(void)
 	 */
 	if (!criticalRelcachesBuilt)
 	{
-		load_critical_index(ClassOidIndexId);
-		load_critical_index(AttributeRelidNumIndexId);
-		load_critical_index(IndexRelidIndexId);
-		load_critical_index(OpclassOidIndexId);
-		load_critical_index(AccessMethodStrategyIndexId);
-		load_critical_index(AccessMethodProcedureIndexId);
-		load_critical_index(OperatorOidIndexId);
-		load_critical_index(RewriteRelRulenameIndexId);
-		load_critical_index(TriggerRelidNameIndexId);
+		load_critical_index(ClassOidIndexId,
+							RelationRelationId);
+		load_critical_index(AttributeRelidNumIndexId,
+							AttributeRelationId);
+		load_critical_index(IndexRelidIndexId,
+							IndexRelationId);
+		load_critical_index(OpclassOidIndexId,
+							OperatorClassRelationId);
+		load_critical_index(AccessMethodStrategyIndexId,
+							AccessMethodOperatorRelationId);
+		load_critical_index(AccessMethodProcedureIndexId,
+							AccessMethodProcedureRelationId);
+		load_critical_index(OperatorOidIndexId,
+							OperatorRelationId);
+		load_critical_index(RewriteRelRulenameIndexId,
+							RewriteRelationId);
+		load_critical_index(TriggerRelidNameIndexId,
+							TriggerRelationId);
 
 #define NUM_CRITICAL_LOCAL_INDEXES	9		/* fix if you change list above */
 
@@ -2744,8 +2755,10 @@ RelationCacheInitializePhase3(void)
 	 */
 	if (!criticalSharedRelcachesBuilt)
 	{
-		load_critical_index(DatabaseNameIndexId);
-		load_critical_index(DatabaseOidIndexId);
+		load_critical_index(DatabaseNameIndexId,
+							DatabaseRelationId);
+		load_critical_index(DatabaseOidIndexId,
+							DatabaseRelationId);
 
 #define NUM_CRITICAL_SHARED_INDEXES	2		/* fix if you change list above */
 
@@ -2886,12 +2899,22 @@ RelationCacheInitializePhase3(void)
 
 /*
  * Load one critical system index into the relcache
+ *
+ * indexoid is the OID of the target index, heapoid is the OID of the catalog
+ * it belongs to.
  */
 static void
-load_critical_index(Oid indexoid)
+load_critical_index(Oid indexoid, Oid heapoid)
 {
 	Relation	ird;
 
+	/*
+	 * We must lock the underlying catalog before locking the index to avoid
+	 * deadlock, since RelationBuildDesc might well need to read the catalog,
+	 * and if anyone else is exclusive-locking this catalog and index they'll
+	 * be doing it in that order.
+	 */
+	LockRelationOid(heapoid, AccessShareLock);
 	LockRelationOid(indexoid, AccessShareLock);
 	ird = RelationBuildDesc(indexoid, true);
 	if (ird == NULL)
@@ -2899,6 +2922,7 @@ load_critical_index(Oid indexoid)
 	ird->rd_isnailed = true;
 	ird->rd_refcnt = 1;
 	UnlockRelationOid(indexoid, AccessShareLock);
+	UnlockRelationOid(heapoid, AccessShareLock);
 }
 
 /*