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

Commit5d1ff6b

Browse files
committed
Fix the logic for putting relations into the relcache init file.
Commitf3b5565 was a couple of bricks shyof a load; specifically, it missed putting pg_trigger_tgrelid_tgname_indexinto the relcache init file, because that index is not used by anysyscache. However, we have historically nailed that index into cache forperformance reasons. The upshot was that load_relcache_init_file alwaysdecided that the init file was busted and silently ignored it, resultingin a significant hit to backend startup speed.To fix, reinstantiate RelationIdIsInInitFile() as a wrapper aroundRelationSupportsSysCache(), which can know about additional relationsthat should be in the init file despite being unknown to syscache.c.Also install some guards against future mistakes of this type: makewrite_relcache_init_file Assert that all nailed relations get written tothe init file, and make load_relcache_init_file emit a WARNING if it takesthe "wrong number of nailed relations" exit path. Now that we remove theinit files during postmaster startup, that case should never occur in thefield, even if we are starting a minor-version update that added or removedrels from the nailed set. So the warning shouldn't ever be seen by endusers, but it will show up in the regression tests if somebody breaks thislogic.Back-patch to all supported branches, like the previous commit.
1 parentd759b7e commit5d1ff6b

File tree

3 files changed

+53
-11
lines changed

3 files changed

+53
-11
lines changed

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

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -509,11 +509,8 @@ RegisterRelcacheInvalidation(Oid dbId, Oid relId)
509509
/*
510510
* If the relation being invalidated is one of those cached in the local
511511
* relcache init file, mark that we need to zap that file at commit.
512-
* (Note: perhaps it would be better if this code were a bit more
513-
* decoupled from the knowledge that the init file contains exactly those
514-
* non-shared rels used in catalog caches.)
515512
*/
516-
if (OidIsValid(dbId)&&RelationSupportsSysCache(relId))
513+
if (OidIsValid(dbId)&&RelationIdIsInInitFile(relId))
517514
transInvalInfo->RelcacheInitFileInval= true;
518515
}
519516

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

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4879,21 +4879,32 @@ load_relcache_init_file(bool shared)
48794879
}
48804880

48814881
/*
4882-
* We reached the end of the init file without apparent problem. Did we
4883-
* get the right number of nailed items? (This is a useful crosscheck in
4884-
* case the set of critical rels or indexes changes.)
4882+
* We reached the end of the init file without apparent problem. Did we
4883+
* get the right number of nailed items? This is a useful crosscheck in
4884+
* case the set of critical rels or indexes changes. However, that should
4885+
* not happen in a normally-running system, so let's bleat if it does.
48854886
*/
48864887
if (shared)
48874888
{
48884889
if (nailed_rels!=NUM_CRITICAL_SHARED_RELS||
48894890
nailed_indexes!=NUM_CRITICAL_SHARED_INDEXES)
4891+
{
4892+
elog(WARNING,"found %d nailed shared rels and %d nailed shared indexes in init file, but expected %d and %d respectively",
4893+
nailed_rels,nailed_indexes,
4894+
NUM_CRITICAL_SHARED_RELS,NUM_CRITICAL_SHARED_INDEXES);
48904895
gotoread_failed;
4896+
}
48914897
}
48924898
else
48934899
{
48944900
if (nailed_rels!=NUM_CRITICAL_LOCAL_RELS||
48954901
nailed_indexes!=NUM_CRITICAL_LOCAL_INDEXES)
4902+
{
4903+
elog(WARNING,"found %d nailed rels and %d nailed indexes in init file, but expected %d and %d respectively",
4904+
nailed_rels,nailed_indexes,
4905+
NUM_CRITICAL_LOCAL_RELS,NUM_CRITICAL_LOCAL_INDEXES);
48964906
gotoread_failed;
4907+
}
48974908
}
48984909

48994910
/*
@@ -5011,12 +5022,19 @@ write_relcache_init_file(bool shared)
50115022
/*
50125023
* Ignore if not supposed to be in init file. We can allow any shared
50135024
* relation that's been loaded so far to be in the shared init file,
5014-
* but unshared relations must be used for catalog caches. (Note: if
5015-
* you want to change the criterion for rels to be kept in the init
5016-
* file, see also inval.c.)
5025+
* but unshared relations must be ones that should be in the local
5026+
* file per RelationIdIsInInitFile. (Note: if you want to change the
5027+
* criterion for rels to be kept in the init file, see also inval.c.
5028+
* The reason for filtering here is to be sure that we don't put
5029+
* anything into the local init file for which a relcache inval would
5030+
* not cause invalidation of that init file.)
50175031
*/
5018-
if (!shared&& !RelationSupportsSysCache(RelationGetRelid(rel)))
5032+
if (!shared&& !RelationIdIsInInitFile(RelationGetRelid(rel)))
5033+
{
5034+
/* Nailed rels had better get stored. */
5035+
Assert(!rel->rd_isnailed);
50195036
continue;
5037+
}
50205038

50215039
/* first write the relcache entry proper */
50225040
write_item(rel,sizeof(RelationData),fp);
@@ -5132,6 +5150,32 @@ write_item(const void *data, Size len, FILE *fp)
51325150
elog(FATAL,"could not write init file");
51335151
}
51345152

5153+
/*
5154+
* Determine whether a given relation (identified by OID) is one of the ones
5155+
* we should store in the local relcache init file.
5156+
*
5157+
* We must cache all nailed rels, and for efficiency we should cache every rel
5158+
* that supports a syscache. The former set is almost but not quite a subset
5159+
* of the latter. Currently, we must special-case TriggerRelidNameIndexId,
5160+
* which RelationCacheInitializePhase3 chooses to nail for efficiency reasons,
5161+
* but which does not support any syscache.
5162+
*
5163+
* Note: this function is currently never called for shared rels. If it were,
5164+
* we'd probably also need a special case for DatabaseNameIndexId, which is
5165+
* critical but does not support a syscache.
5166+
*/
5167+
bool
5168+
RelationIdIsInInitFile(OidrelationId)
5169+
{
5170+
if (relationId==TriggerRelidNameIndexId)
5171+
{
5172+
/* If this Assert fails, we don't need this special case anymore. */
5173+
Assert(!RelationSupportsSysCache(relationId));
5174+
return true;
5175+
}
5176+
returnRelationSupportsSysCache(relationId);
5177+
}
5178+
51355179
/*
51365180
* Invalidate (remove) the init file during commit of a transaction that
51375181
* changed one or more of the relation cache entries that are kept in the

‎src/include/utils/relcache.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ extern void AtEOSubXact_RelationCache(bool isCommit, SubTransactionId mySubid,
116116
/*
117117
* Routines to help manage rebuilding of relcache init files
118118
*/
119+
externboolRelationIdIsInInitFile(OidrelationId);
119120
externvoidRelationCacheInitFilePreInvalidate(void);
120121
externvoidRelationCacheInitFilePostInvalidate(void);
121122
externvoidRelationCacheInitFileRemove(void);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp