8
8
*
9
9
*
10
10
* 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 $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
46
46
#include "catalog/pg_database.h"
47
47
#include "catalog/pg_namespace.h"
48
48
#include "catalog/pg_opclass.h"
49
+ #include "catalog/pg_operator.h"
49
50
#include "catalog/pg_proc.h"
50
51
#include "catalog/pg_rewrite.h"
51
52
#include "catalog/pg_tablespace.h"
53
+ #include "catalog/pg_trigger.h"
52
54
#include "catalog/pg_type.h"
53
55
#include "catalog/schemapg.h"
54
56
#include "commands/trigger.h"
@@ -217,7 +219,7 @@ static void RelationParseRelOptions(Relation relation, HeapTuple tuple);
217
219
static void RelationBuildTupleDesc (Relation relation );
218
220
static Relation RelationBuildDesc (Oid targetRelId , bool insertIt );
219
221
static void RelationInitPhysicalAddr (Relation relation );
220
- static void load_critical_index (Oid indexoid );
222
+ static void load_critical_index (Oid indexoid , Oid heapoid );
221
223
static TupleDesc GetPgClassDescriptor (void );
222
224
static TupleDesc GetPgIndexDescriptor (void );
223
225
static void AttrDefaultFetch (Relation relation );
@@ -2719,15 +2721,24 @@ RelationCacheInitializePhase3(void)
2719
2721
*/
2720
2722
if (!criticalRelcachesBuilt )
2721
2723
{
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 );
2731
2742
2732
2743
#define NUM_CRITICAL_LOCAL_INDEXES 9 /* fix if you change list above */
2733
2744
@@ -2744,8 +2755,10 @@ RelationCacheInitializePhase3(void)
2744
2755
*/
2745
2756
if (!criticalSharedRelcachesBuilt )
2746
2757
{
2747
- load_critical_index (DatabaseNameIndexId );
2748
- load_critical_index (DatabaseOidIndexId );
2758
+ load_critical_index (DatabaseNameIndexId ,
2759
+ DatabaseRelationId );
2760
+ load_critical_index (DatabaseOidIndexId ,
2761
+ DatabaseRelationId );
2749
2762
2750
2763
#define NUM_CRITICAL_SHARED_INDEXES 2 /* fix if you change list above */
2751
2764
@@ -2886,19 +2899,30 @@ RelationCacheInitializePhase3(void)
2886
2899
2887
2900
/*
2888
2901
* 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.
2889
2905
*/
2890
2906
static void
2891
- load_critical_index (Oid indexoid )
2907
+ load_critical_index (Oid indexoid , Oid heapoid )
2892
2908
{
2893
2909
Relation ird ;
2894
2910
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 );
2895
2918
LockRelationOid (indexoid , AccessShareLock );
2896
2919
ird = RelationBuildDesc (indexoid , true);
2897
2920
if (ird == NULL )
2898
2921
elog (PANIC , "could not open critical system index %u" , indexoid );
2899
2922
ird -> rd_isnailed = true;
2900
2923
ird -> rd_refcnt = 1 ;
2901
2924
UnlockRelationOid (indexoid , AccessShareLock );
2925
+ UnlockRelationOid (heapoid , AccessShareLock );
2902
2926
}
2903
2927
2904
2928
/*
0 commit comments