88 *
99 *
1010 * IDENTIFICATION
11- * $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.299 2010/01/12 18:12:18 tgl Exp $
11+ * $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.300 2010/01/13 23:07:08 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
4646#include "catalog/pg_database.h"
4747#include "catalog/pg_namespace.h"
4848#include "catalog/pg_opclass.h"
49+ #include "catalog/pg_operator.h"
4950#include "catalog/pg_proc.h"
5051#include "catalog/pg_rewrite.h"
5152#include "catalog/pg_tablespace.h"
53+ #include "catalog/pg_trigger.h"
5254#include "catalog/pg_type.h"
5355#include "catalog/schemapg.h"
5456#include "commands/trigger.h"
@@ -217,7 +219,7 @@ static void RelationParseRelOptions(Relation relation, HeapTuple tuple);
217219static void RelationBuildTupleDesc (Relation relation );
218220static Relation RelationBuildDesc (Oid targetRelId , bool insertIt );
219221static void RelationInitPhysicalAddr (Relation relation );
220- static void load_critical_index (Oid indexoid );
222+ static void load_critical_index (Oid indexoid , Oid heapoid );
221223static TupleDesc GetPgClassDescriptor (void );
222224static TupleDesc GetPgIndexDescriptor (void );
223225static void AttrDefaultFetch (Relation relation );
@@ -2719,15 +2721,24 @@ RelationCacheInitializePhase3(void)
27192721 */
27202722 if (!criticalRelcachesBuilt )
27212723 {
2722- load_critical_index (ClassOidIndexId );
2723- load_critical_index (AttributeRelidNumIndexId );
2724- load_critical_index (IndexRelidIndexId );
2725- load_critical_index (OpclassOidIndexId );
2726- load_critical_index (AccessMethodStrategyIndexId );
2727- load_critical_index (AccessMethodProcedureIndexId );
2728- load_critical_index (OperatorOidIndexId );
2729- load_critical_index (RewriteRelRulenameIndexId );
2730- load_critical_index (TriggerRelidNameIndexId );
2724+ load_critical_index (ClassOidIndexId ,
2725+ RelationRelationId );
2726+ load_critical_index (AttributeRelidNumIndexId ,
2727+ AttributeRelationId );
2728+ load_critical_index (IndexRelidIndexId ,
2729+ IndexRelationId );
2730+ load_critical_index (OpclassOidIndexId ,
2731+ OperatorClassRelationId );
2732+ load_critical_index (AccessMethodStrategyIndexId ,
2733+ AccessMethodOperatorRelationId );
2734+ load_critical_index (AccessMethodProcedureIndexId ,
2735+ AccessMethodProcedureRelationId );
2736+ load_critical_index (OperatorOidIndexId ,
2737+ OperatorRelationId );
2738+ load_critical_index (RewriteRelRulenameIndexId ,
2739+ RewriteRelationId );
2740+ load_critical_index (TriggerRelidNameIndexId ,
2741+ TriggerRelationId );
27312742
27322743#define NUM_CRITICAL_LOCAL_INDEXES 9 /* fix if you change list above */
27332744
@@ -2744,8 +2755,10 @@ RelationCacheInitializePhase3(void)
27442755 */
27452756 if (!criticalSharedRelcachesBuilt )
27462757 {
2747- load_critical_index (DatabaseNameIndexId );
2748- load_critical_index (DatabaseOidIndexId );
2758+ load_critical_index (DatabaseNameIndexId ,
2759+ DatabaseRelationId );
2760+ load_critical_index (DatabaseOidIndexId ,
2761+ DatabaseRelationId );
27492762
27502763#define NUM_CRITICAL_SHARED_INDEXES 2 /* fix if you change list above */
27512764
@@ -2886,19 +2899,30 @@ RelationCacheInitializePhase3(void)
28862899
28872900/*
28882901 * Load one critical system index into the relcache
2902+ *
2903+ * indexoid is the OID of the target index, heapoid is the OID of the catalog
2904+ * it belongs to.
28892905 */
28902906static void
2891- load_critical_index (Oid indexoid )
2907+ load_critical_index (Oid indexoid , Oid heapoid )
28922908{
28932909 Relation ird ;
28942910
2911+ /*
2912+ * We must lock the underlying catalog before locking the index to avoid
2913+ * deadlock, since RelationBuildDesc might well need to read the catalog,
2914+ * and if anyone else is exclusive-locking this catalog and index they'll
2915+ * be doing it in that order.
2916+ */
2917+ LockRelationOid (heapoid , AccessShareLock );
28952918 LockRelationOid (indexoid , AccessShareLock );
28962919 ird = RelationBuildDesc (indexoid , true);
28972920 if (ird == NULL )
28982921 elog (PANIC , "could not open critical system index %u" , indexoid );
28992922 ird -> rd_isnailed = true;
29002923 ird -> rd_refcnt = 1 ;
29012924 UnlockRelationOid (indexoid , AccessShareLock );
2925+ UnlockRelationOid (heapoid , AccessShareLock );
29022926}
29032927
29042928/*
0 commit comments