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

Commitb7a98b1

Browse files
committed
Avoid searching for the target catcache in CatalogCacheIdInvalidate.
A test case provided by Mathieu Fenniak shows that the initial search forthe target catcache in CatalogCacheIdInvalidate consumes a very significantamount of overhead in cases where cache invalidation is triggered but haslittle useful work to do. There is no good reason for that search to existat all, as the index array maintained by syscache.c allows direct lookup ofthe catcache from its ID. We just need a frontend function in syscache.c,matching the division of labor for most other cache-accessing operations.While there's more that can be done in this area, this patch alone reducesthe runtime of Mathieu's example by 2X. We can hope that it offers someuseful benefit in other cases too, although usually cache invalidationoverhead is not such a striking fraction of the total runtime.Back-patch to 9.4 where logical decoding was introduced. It might beworth going further back, but presently the only case we know of wherecache invalidation is really a significant burden is in logical decoding.Also, older branches have fewer catcaches, reducing the possible benefit.(Note: although this nominally changes catcache's API, we have alwaysdocumented CatalogCacheIdInvalidate as a private function, so I wouldhave little sympathy for an external module calling it directly. Sobackpatching should be fine.)Discussion:https://postgr.es/m/CAHoiPjzea6N0zuCi=+f9v_j94nfsy6y8SU7-=bp4=7qw6_i=Rg@mail.gmail.com
1 parentcb701af commitb7a98b1

File tree

5 files changed

+64
-55
lines changed

5 files changed

+64
-55
lines changed

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

Lines changed: 39 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,7 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
427427

428428

429429
/*
430-
*CatalogCacheIdInvalidate
430+
*CatCacheInvalidate
431431
*
432432
*Invalidate entries in the specified cache, given a hash value.
433433
*
@@ -445,71 +445,57 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
445445
*This routine is only quasi-public: it should only be used by inval.c.
446446
*/
447447
void
448-
CatalogCacheIdInvalidate(intcacheId,uint32hashValue)
448+
CatCacheInvalidate(CatCache*cache,uint32hashValue)
449449
{
450-
slist_itercache_iter;
450+
IndexhashIndex;
451+
dlist_mutable_iteriter;
451452

452-
CACHE1_elog(DEBUG2,"CatalogCacheIdInvalidate: called");
453+
CACHE1_elog(DEBUG2,"CatCacheInvalidate: called");
453454

454455
/*
455-
* inspect caches to find the proper cache
456+
* We don't bother to check whether the cache has finished initialization
457+
* yet; if not, there will be no entries in it so no problem.
456458
*/
457-
slist_foreach(cache_iter,&CacheHdr->ch_caches)
458-
{
459-
CatCache*ccp=slist_container(CatCache,cc_next,cache_iter.cur);
460-
IndexhashIndex;
461-
dlist_mutable_iteriter;
462-
463-
if (cacheId!=ccp->id)
464-
continue;
465459

466-
/*
467-
* We don't bother to check whether the cache has finished
468-
* initialization yet; if not, there will be no entries in it so no
469-
* problem.
470-
*/
460+
/*
461+
* Invalidate *all* CatCLists in this cache; it's too hard to tell which
462+
* searches might still be correct, so just zap 'em all.
463+
*/
464+
dlist_foreach_modify(iter,&cache->cc_lists)
465+
{
466+
CatCList*cl=dlist_container(CatCList,cache_elem,iter.cur);
471467

472-
/*
473-
* Invalidate *all* CatCLists in this cache; it's too hard to tell
474-
* which searches might still be correct, so just zap 'em all.
475-
*/
476-
dlist_foreach_modify(iter,&ccp->cc_lists)
477-
{
478-
CatCList*cl=dlist_container(CatCList,cache_elem,iter.cur);
468+
if (cl->refcount>0)
469+
cl->dead= true;
470+
else
471+
CatCacheRemoveCList(cache,cl);
472+
}
479473

480-
if (cl->refcount>0)
481-
cl->dead= true;
482-
else
483-
CatCacheRemoveCList(ccp,cl);
484-
}
474+
/*
475+
* inspect the proper hash bucket for tuple matches
476+
*/
477+
hashIndex=HASH_INDEX(hashValue,cache->cc_nbuckets);
478+
dlist_foreach_modify(iter,&cache->cc_bucket[hashIndex])
479+
{
480+
CatCTup*ct=dlist_container(CatCTup,cache_elem,iter.cur);
485481

486-
/*
487-
* inspect the proper hash bucket for tuple matches
488-
*/
489-
hashIndex=HASH_INDEX(hashValue,ccp->cc_nbuckets);
490-
dlist_foreach_modify(iter,&ccp->cc_bucket[hashIndex])
482+
if (hashValue==ct->hash_value)
491483
{
492-
CatCTup*ct=dlist_container(CatCTup,cache_elem,iter.cur);
493-
494-
if (hashValue==ct->hash_value)
484+
if (ct->refcount>0||
485+
(ct->c_list&&ct->c_list->refcount>0))
495486
{
496-
if (ct->refcount>0||
497-
(ct->c_list&&ct->c_list->refcount>0))
498-
{
499-
ct->dead= true;
500-
/* list, if any, was marked dead above */
501-
Assert(ct->c_list==NULL||ct->c_list->dead);
502-
}
503-
else
504-
CatCacheRemoveCTup(ccp,ct);
505-
CACHE1_elog(DEBUG2,"CatalogCacheIdInvalidate: invalidated");
487+
ct->dead= true;
488+
/* list, if any, was marked dead above */
489+
Assert(ct->c_list==NULL||ct->c_list->dead);
490+
}
491+
else
492+
CatCacheRemoveCTup(cache,ct);
493+
CACHE1_elog(DEBUG2,"CatCacheInvalidate: invalidated");
506494
#ifdefCATCACHE_STATS
507-
ccp->cc_invals++;
495+
cache->cc_invals++;
508496
#endif
509-
/* could be multiple matches, so keep looking! */
510-
}
497+
/* could be multiple matches, so keep looking! */
511498
}
512-
break;/* need only search this one cache */
513499
}
514500
}
515501

@@ -1828,7 +1814,7 @@ build_dummy_tuple(CatCache *cache, int nkeys, ScanKey skeys)
18281814
*the specified relation, find all catcaches it could be in, compute the
18291815
*correct hash value for each such catcache, and call the specified
18301816
*function to record the cache id and hash value in inval.c's lists.
1831-
*CatalogCacheIdInvalidate will be called later, if appropriate,
1817+
*SysCacheInvalidate will be called later, if appropriate,
18321818
*using the recorded information.
18331819
*
18341820
*For an insert or delete, tuple is the target tuple and newtuple is NULL.

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -543,7 +543,7 @@ LocalExecuteInvalidationMessage(SharedInvalidationMessage *msg)
543543
{
544544
InvalidateCatalogSnapshot();
545545

546-
CatalogCacheIdInvalidate(msg->cc.id,msg->cc.hashValue);
546+
SysCacheInvalidate(msg->cc.id,msg->cc.hashValue);
547547

548548
CallSyscacheCallbacks(msg->cc.id,msg->cc.hashValue);
549549
}

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1212,6 +1212,27 @@ SearchSysCacheList(int cacheId, int nkeys,
12121212
key1,key2,key3,key4);
12131213
}
12141214

1215+
/*
1216+
* SysCacheInvalidate
1217+
*
1218+
*Invalidate entries in the specified cache, given a hash value.
1219+
*See CatCacheInvalidate() for more info.
1220+
*
1221+
*This routine is only quasi-public: it should only be used by inval.c.
1222+
*/
1223+
void
1224+
SysCacheInvalidate(intcacheId,uint32hashValue)
1225+
{
1226+
if (cacheId<0||cacheId >=SysCacheSize)
1227+
elog(ERROR,"invalid cache ID: %d",cacheId);
1228+
1229+
/* if this cache isn't initialized yet, no need to do anything */
1230+
if (!PointerIsValid(SysCache[cacheId]))
1231+
return;
1232+
1233+
CatCacheInvalidate(SysCache[cacheId],hashValue);
1234+
}
1235+
12151236
/*
12161237
* Certain relations that do not have system caches send snapshot invalidation
12171238
* messages in lieu of catcache messages. This is for the benefit of

‎src/include/utils/catcache.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ extern void ReleaseCatCacheList(CatCList *list);
185185

186186
externvoidResetCatalogCaches(void);
187187
externvoidCatalogCacheFlushCatalog(OidcatId);
188-
externvoidCatalogCacheIdInvalidate(intcacheId,uint32hashValue);
188+
externvoidCatCacheInvalidate(CatCache*cache,uint32hashValue);
189189
externvoidPrepareToInvalidateCacheTuple(Relationrelation,
190190
HeapTupletuple,
191191
HeapTuplenewtuple,

‎src/include/utils/syscache.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,8 @@ struct catclist;
129129
externstructcatclist*SearchSysCacheList(intcacheId,intnkeys,
130130
Datumkey1,Datumkey2,Datumkey3,Datumkey4);
131131

132+
externvoidSysCacheInvalidate(intcacheId,uint32hashValue);
133+
132134
externboolRelationInvalidatesSnapshotsOnly(Oidrelid);
133135
externboolRelationHasSysCache(Oidrelid);
134136
externboolRelationSupportsSysCache(Oidrelid);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp