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

Commit50ee1c7

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 parent928c4de commit50ee1c7

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
@@ -422,7 +422,7 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
422422

423423

424424
/*
425-
*CatalogCacheIdInvalidate
425+
*CatCacheInvalidate
426426
*
427427
*Invalidate entries in the specified cache, given a hash value.
428428
*
@@ -440,71 +440,57 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
440440
*This routine is only quasi-public: it should only be used by inval.c.
441441
*/
442442
void
443-
CatalogCacheIdInvalidate(intcacheId,uint32hashValue)
443+
CatCacheInvalidate(CatCache*cache,uint32hashValue)
444444
{
445-
slist_itercache_iter;
445+
IndexhashIndex;
446+
dlist_mutable_iteriter;
446447

447-
CACHE1_elog(DEBUG2,"CatalogCacheIdInvalidate: called");
448+
CACHE1_elog(DEBUG2,"CatCacheInvalidate: called");
448449

449450
/*
450-
* inspect caches to find the proper cache
451+
* We don't bother to check whether the cache has finished initialization
452+
* yet; if not, there will be no entries in it so no problem.
451453
*/
452-
slist_foreach(cache_iter,&CacheHdr->ch_caches)
453-
{
454-
CatCache*ccp=slist_container(CatCache,cc_next,cache_iter.cur);
455-
IndexhashIndex;
456-
dlist_mutable_iteriter;
457-
458-
if (cacheId!=ccp->id)
459-
continue;
460454

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

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

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

481-
/*
482-
* inspect the proper hash bucket for tuple matches
483-
*/
484-
hashIndex=HASH_INDEX(hashValue,ccp->cc_nbuckets);
485-
dlist_foreach_modify(iter,&ccp->cc_bucket[hashIndex])
477+
if (hashValue==ct->hash_value)
486478
{
487-
CatCTup*ct=dlist_container(CatCTup,cache_elem,iter.cur);
488-
489-
if (hashValue==ct->hash_value)
479+
if (ct->refcount>0||
480+
(ct->c_list&&ct->c_list->refcount>0))
490481
{
491-
if (ct->refcount>0||
492-
(ct->c_list&&ct->c_list->refcount>0))
493-
{
494-
ct->dead= true;
495-
/* list, if any, was marked dead above */
496-
Assert(ct->c_list==NULL||ct->c_list->dead);
497-
}
498-
else
499-
CatCacheRemoveCTup(ccp,ct);
500-
CACHE1_elog(DEBUG2,"CatalogCacheIdInvalidate: invalidated");
482+
ct->dead= true;
483+
/* list, if any, was marked dead above */
484+
Assert(ct->c_list==NULL||ct->c_list->dead);
485+
}
486+
else
487+
CatCacheRemoveCTup(cache,ct);
488+
CACHE1_elog(DEBUG2,"CatCacheInvalidate: invalidated");
501489
#ifdefCATCACHE_STATS
502-
ccp->cc_invals++;
490+
cache->cc_invals++;
503491
#endif
504-
/* could be multiple matches, so keep looking! */
505-
}
492+
/* could be multiple matches, so keep looking! */
506493
}
507-
break;/* need only search this one cache */
508494
}
509495
}
510496

@@ -1823,7 +1809,7 @@ build_dummy_tuple(CatCache *cache, int nkeys, ScanKey skeys)
18231809
*the specified relation, find all catcaches it could be in, compute the
18241810
*correct hash value for each such catcache, and call the specified
18251811
*function to record the cache id and hash value in inval.c's lists.
1826-
*CatalogCacheIdInvalidate will be called later, if appropriate,
1812+
*SysCacheInvalidate will be called later, if appropriate,
18271813
*using the recorded information.
18281814
*
18291815
*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
@@ -552,7 +552,7 @@ LocalExecuteInvalidationMessage(SharedInvalidationMessage *msg)
552552
{
553553
InvalidateCatalogSnapshot();
554554

555-
CatalogCacheIdInvalidate(msg->cc.id,msg->cc.hashValue);
555+
SysCacheInvalidate(msg->cc.id,msg->cc.hashValue);
556556

557557
CallSyscacheCallbacks(msg->cc.id,msg->cc.hashValue);
558558
}

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1338,6 +1338,27 @@ SearchSysCacheList(int cacheId, int nkeys,
13381338
key1,key2,key3,key4);
13391339
}
13401340

1341+
/*
1342+
* SysCacheInvalidate
1343+
*
1344+
*Invalidate entries in the specified cache, given a hash value.
1345+
*See CatCacheInvalidate() for more info.
1346+
*
1347+
*This routine is only quasi-public: it should only be used by inval.c.
1348+
*/
1349+
void
1350+
SysCacheInvalidate(intcacheId,uint32hashValue)
1351+
{
1352+
if (cacheId<0||cacheId >=SysCacheSize)
1353+
elog(ERROR,"invalid cache ID: %d",cacheId);
1354+
1355+
/* if this cache isn't initialized yet, no need to do anything */
1356+
if (!PointerIsValid(SysCache[cacheId]))
1357+
return;
1358+
1359+
CatCacheInvalidate(SysCache[cacheId],hashValue);
1360+
}
1361+
13411362
/*
13421363
* Certain relations that do not have system caches send snapshot invalidation
13431364
* 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
@@ -190,7 +190,7 @@ extern void ReleaseCatCacheList(CatCList *list);
190190

191191
externvoidResetCatalogCaches(void);
192192
externvoidCatalogCacheFlushCatalog(OidcatId);
193-
externvoidCatalogCacheIdInvalidate(intcacheId,uint32hashValue);
193+
externvoidCatCacheInvalidate(CatCache*cache,uint32hashValue);
194194
externvoidPrepareToInvalidateCacheTuple(Relationrelation,
195195
HeapTupletuple,
196196
HeapTuplenewtuple,

‎src/include/utils/syscache.h

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

143+
externvoidSysCacheInvalidate(intcacheId,uint32hashValue);
144+
143145
externboolRelationInvalidatesSnapshotsOnly(Oidrelid);
144146
externboolRelationHasSysCache(Oidrelid);
145147
externboolRelationSupportsSysCache(Oidrelid);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp