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

Commit0f45d1e

Browse files
committed
Fix LOAD_CRIT_INDEX() macro to take out AccessShareLock on the system index
it is trying to build a relcache entry for. This is an oversight in my 8.2patch that tried to ensure we always took a lock on a relation before tryingto build its relcache entry. The implication is that if someone committed areindex of a critical system index at about the same time that some otherbackend were starting up without a valid pg_internal.init file, the second onemight PANIC due to not seeing any valid version of the index's pg_class row.Improbable case, but definitely not impossible.
1 parenta9b3e4f commit0f45d1e

File tree

1 file changed

+18
-6
lines changed

1 file changed

+18
-6
lines changed

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

Lines changed: 18 additions & 6 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.270 2008/04/01 00:48:33 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.271 2008/04/16 18:23:04 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -220,8 +220,11 @@ static OpClassCacheEnt *LookupOpclassInfo(Oid operatorClassOid,
220220
/*
221221
*ScanPgRelation
222222
*
223-
*this is used by RelationBuildDesc to find a pg_class
224-
*tuple matching targetRelId.
223+
*This is used by RelationBuildDesc to find a pg_class
224+
*tuple matching targetRelId. The caller must hold at least
225+
*AccessShareLock on the target relid to prevent concurrent-update
226+
*scenarios --- else our SnapshotNow scan might fail to find any
227+
*version that it thinks is live.
225228
*
226229
*NB: the returned tuple has been copied into palloc'd storage
227230
*and must eventually be freed with heap_freetuple.
@@ -773,18 +776,18 @@ equalRuleLocks(RuleLock *rlock1, RuleLock *rlock2)
773776
}
774777

775778

776-
/* ----------------------------------
779+
/*
777780
*RelationBuildDesc
778781
*
779782
*Build a relation descriptor --- either a new one, or by
780783
*recycling the given old relation object. The latter case
781784
*supports rebuilding a relcache entry without invalidating
782-
*pointers to it.
785+
*pointers to it. The caller must hold at least
786+
*AccessShareLock on the target relid.
783787
*
784788
*Returns NULL if no pg_class row could be found for the given relid
785789
*(suggesting we are trying to access a just-deleted relation).
786790
*Any other error is reported via elog.
787-
* --------------------------------
788791
*/
789792
staticRelation
790793
RelationBuildDesc(OidtargetRelId,Relationoldrelation)
@@ -1608,6 +1611,10 @@ RelationClose(Relation relation)
16081611
*RelationClearRelation just marks the entry as invalid by setting
16091612
*rd_isvalid to false. This routine is called to fix the entry when it
16101613
*is next needed.
1614+
*
1615+
*We assume that at the time we are called, we have at least AccessShareLock
1616+
*on the target index. (Note: in the calls from RelationClearRelation,
1617+
*this is legitimate because we know the rel has positive refcount.)
16111618
*/
16121619
staticvoid
16131620
RelationReloadIndexInfo(Relationrelation)
@@ -1692,6 +1699,9 @@ RelationReloadIndexInfo(Relation relation)
16921699
* usually used when we are notified of a change to an open relation
16931700
* (one with refcount > 0). However, this routine just does whichever
16941701
* it's told to do; callers must determine which they want.
1702+
*
1703+
* NB: when rebuilding, we'd better hold some lock on the relation.
1704+
* In current usages this is presumed true because it has refcnt > 0.
16951705
*/
16961706
staticvoid
16971707
RelationClearRelation(Relationrelation,boolrebuild)
@@ -2542,12 +2552,14 @@ RelationCacheInitializePhase2(void)
25422552

25432553
#defineLOAD_CRIT_INDEX(indexoid) \
25442554
do { \
2555+
LockRelationOid(indexoid, AccessShareLock); \
25452556
ird = RelationBuildDesc(indexoid, NULL); \
25462557
if (ird == NULL) \
25472558
elog(PANIC, "could not open critical system index %u", \
25482559
indexoid); \
25492560
ird->rd_isnailed = true; \
25502561
ird->rd_refcnt = 1; \
2562+
UnlockRelationOid(indexoid, AccessShareLock); \
25512563
} while (0)
25522564

25532565
LOAD_CRIT_INDEX(ClassOidIndexId);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp