Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit715120e

Browse files
committed
When loading critical system indexes into the relcache, ensure we lock the
underlying catalog not only the index itself. Otherwise, if the cacheload process touches the catalog (which will happen for many though notall of these indexes), we are locking index before parent table, which canresult in a deadlock against processes that are trying to lock them in thenormal order. Per today's failure on buildfarm member gothic_moth; it'ssurprising the problem hadn't been identified before.Back-patch to 8.2. Earlier releases didn't have the issue because theydidn't try to lock these indexes during load (instead assuming that theycouldn't change schema at all during multiuser operation).
1 parentdbba3a1 commit715120e

File tree

1 file changed

+38
-14
lines changed

1 file changed

+38
-14
lines changed

‎src/backend/utils/cache/relcache.c

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
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
*/
@@ -46,9 +46,11 @@
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);
217219
staticvoidRelationBuildTupleDesc(Relationrelation);
218220
staticRelationRelationBuildDesc(OidtargetRelId,boolinsertIt);
219221
staticvoidRelationInitPhysicalAddr(Relationrelation);
220-
staticvoidload_critical_index(Oidindexoid);
222+
staticvoidload_critical_index(Oidindexoid,Oidheapoid);
221223
staticTupleDescGetPgClassDescriptor(void);
222224
staticTupleDescGetPgIndexDescriptor(void);
223225
staticvoidAttrDefaultFetch(Relationrelation);
@@ -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
#defineNUM_CRITICAL_LOCAL_INDEXES9/* 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
#defineNUM_CRITICAL_SHARED_INDEXES2/* 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
*/
28902906
staticvoid
2891-
load_critical_index(Oidindexoid)
2907+
load_critical_index(Oidindexoid,Oidheapoid)
28922908
{
28932909
Relationird;
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

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp