
A test case provided by Mathieu Fenniak shows that the initial search for the target catcache in CatalogCacheIdInvalidate consumes a very significant amount of overhead in cases where cache invalidation is triggered but has little useful work to do. There is no good reason for that search to exist at all, as the index array maintained by syscache.c allows direct lookup of the 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 reduces the runtime of Mathieu's example by 2X. We can hope that it offers some useful benefit in other cases too, although usually cache invalidation overhead is not such a striking fraction of the total runtime. Back-patch to 9.4 where logical decoding was introduced. It might be worth going further back, but presently the only case we know of where cache 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 always documented CatalogCacheIdInvalidate as a private function, so I would have little sympathy for an external module calling it directly. So backpatching should be fine.) Discussion: https://postgr.es/m/CAHoiPjzea6N0zuCi=+f9v_j94nfsy6y8SU7-=bp4=7qw6_i=Rg@mail.gmail.com
211 lines
6.0 KiB
C
211 lines
6.0 KiB
C
/*-------------------------------------------------------------------------
|
|
*
|
|
* syscache.h
|
|
* System catalog cache definitions.
|
|
*
|
|
* See also lsyscache.h, which provides convenience routines for
|
|
* common cache-lookup operations.
|
|
*
|
|
* Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
|
*
|
|
* src/include/utils/syscache.h
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
#ifndef SYSCACHE_H
|
|
#define SYSCACHE_H
|
|
|
|
#include "access/attnum.h"
|
|
#include "access/htup.h"
|
|
/* we intentionally do not include utils/catcache.h here */
|
|
|
|
/*
|
|
* SysCache identifiers.
|
|
*
|
|
* The order of these identifiers must match the order
|
|
* of the entries in the array cacheinfo[] in syscache.c.
|
|
* Keep them in alphabetical order (renumbering only costs a
|
|
* backend rebuild).
|
|
*/
|
|
|
|
enum SysCacheIdentifier
|
|
{
|
|
AGGFNOID = 0,
|
|
AMNAME,
|
|
AMOID,
|
|
AMOPOPID,
|
|
AMOPSTRATEGY,
|
|
AMPROCNUM,
|
|
ATTNAME,
|
|
ATTNUM,
|
|
AUTHMEMMEMROLE,
|
|
AUTHMEMROLEMEM,
|
|
AUTHNAME,
|
|
AUTHOID,
|
|
CASTSOURCETARGET,
|
|
CLAAMNAMENSP,
|
|
CLAOID,
|
|
COLLNAMEENCNSP,
|
|
COLLOID,
|
|
CONDEFAULT,
|
|
CONNAMENSP,
|
|
CONSTROID,
|
|
CONVOID,
|
|
DATABASEOID,
|
|
DEFACLROLENSPOBJ,
|
|
ENUMOID,
|
|
ENUMTYPOIDNAME,
|
|
EVENTTRIGGERNAME,
|
|
EVENTTRIGGEROID,
|
|
FOREIGNDATAWRAPPERNAME,
|
|
FOREIGNDATAWRAPPEROID,
|
|
FOREIGNSERVERNAME,
|
|
FOREIGNSERVEROID,
|
|
FOREIGNTABLEREL,
|
|
INDEXRELID,
|
|
LANGNAME,
|
|
LANGOID,
|
|
NAMESPACENAME,
|
|
NAMESPACEOID,
|
|
OPERNAMENSP,
|
|
OPEROID,
|
|
OPFAMILYAMNAMENSP,
|
|
OPFAMILYOID,
|
|
PARTRELID,
|
|
PROCNAMEARGSNSP,
|
|
PROCOID,
|
|
RANGETYPE,
|
|
RELNAMENSP,
|
|
RELOID,
|
|
REPLORIGIDENT,
|
|
REPLORIGNAME,
|
|
PUBLICATIONOID,
|
|
PUBLICATIONNAME,
|
|
PUBLICATIONREL,
|
|
PUBLICATIONRELMAP,
|
|
RULERELNAME,
|
|
SEQRELID,
|
|
STATEXTNAMENSP,
|
|
STATEXTOID,
|
|
STATRELATTINH,
|
|
SUBSCRIPTIONOID,
|
|
SUBSCRIPTIONNAME,
|
|
SUBSCRIPTIONRELMAP,
|
|
TABLESPACEOID,
|
|
TRFOID,
|
|
TRFTYPELANG,
|
|
TSCONFIGMAP,
|
|
TSCONFIGNAMENSP,
|
|
TSCONFIGOID,
|
|
TSDICTNAMENSP,
|
|
TSDICTOID,
|
|
TSPARSERNAMENSP,
|
|
TSPARSEROID,
|
|
TSTEMPLATENAMENSP,
|
|
TSTEMPLATEOID,
|
|
TYPENAMENSP,
|
|
TYPEOID,
|
|
USERMAPPINGOID,
|
|
USERMAPPINGUSERSERVER
|
|
};
|
|
|
|
extern void InitCatalogCache(void);
|
|
extern void InitCatalogCachePhase2(void);
|
|
|
|
extern HeapTuple SearchSysCache(int cacheId,
|
|
Datum key1, Datum key2, Datum key3, Datum key4);
|
|
extern void ReleaseSysCache(HeapTuple tuple);
|
|
|
|
/* convenience routines */
|
|
extern HeapTuple SearchSysCacheCopy(int cacheId,
|
|
Datum key1, Datum key2, Datum key3, Datum key4);
|
|
extern bool SearchSysCacheExists(int cacheId,
|
|
Datum key1, Datum key2, Datum key3, Datum key4);
|
|
extern Oid GetSysCacheOid(int cacheId,
|
|
Datum key1, Datum key2, Datum key3, Datum key4);
|
|
|
|
extern HeapTuple SearchSysCacheAttName(Oid relid, const char *attname);
|
|
extern HeapTuple SearchSysCacheCopyAttName(Oid relid, const char *attname);
|
|
extern bool SearchSysCacheExistsAttName(Oid relid, const char *attname);
|
|
|
|
extern Datum SysCacheGetAttr(int cacheId, HeapTuple tup,
|
|
AttrNumber attributeNumber, bool *isNull);
|
|
|
|
extern uint32 GetSysCacheHashValue(int cacheId,
|
|
Datum key1, Datum key2, Datum key3, Datum key4);
|
|
|
|
/* list-search interface. Users of this must import catcache.h too */
|
|
struct catclist;
|
|
extern struct catclist *SearchSysCacheList(int cacheId, int nkeys,
|
|
Datum key1, Datum key2, Datum key3, Datum key4);
|
|
|
|
extern void SysCacheInvalidate(int cacheId, uint32 hashValue);
|
|
|
|
extern bool RelationInvalidatesSnapshotsOnly(Oid relid);
|
|
extern bool RelationHasSysCache(Oid relid);
|
|
extern bool RelationSupportsSysCache(Oid relid);
|
|
|
|
/*
|
|
* The use of the macros below rather than direct calls to the corresponding
|
|
* functions is encouraged, as it insulates the caller from changes in the
|
|
* maximum number of keys.
|
|
*/
|
|
#define SearchSysCache1(cacheId, key1) \
|
|
SearchSysCache(cacheId, key1, 0, 0, 0)
|
|
#define SearchSysCache2(cacheId, key1, key2) \
|
|
SearchSysCache(cacheId, key1, key2, 0, 0)
|
|
#define SearchSysCache3(cacheId, key1, key2, key3) \
|
|
SearchSysCache(cacheId, key1, key2, key3, 0)
|
|
#define SearchSysCache4(cacheId, key1, key2, key3, key4) \
|
|
SearchSysCache(cacheId, key1, key2, key3, key4)
|
|
|
|
#define SearchSysCacheCopy1(cacheId, key1) \
|
|
SearchSysCacheCopy(cacheId, key1, 0, 0, 0)
|
|
#define SearchSysCacheCopy2(cacheId, key1, key2) \
|
|
SearchSysCacheCopy(cacheId, key1, key2, 0, 0)
|
|
#define SearchSysCacheCopy3(cacheId, key1, key2, key3) \
|
|
SearchSysCacheCopy(cacheId, key1, key2, key3, 0)
|
|
#define SearchSysCacheCopy4(cacheId, key1, key2, key3, key4) \
|
|
SearchSysCacheCopy(cacheId, key1, key2, key3, key4)
|
|
|
|
#define SearchSysCacheExists1(cacheId, key1) \
|
|
SearchSysCacheExists(cacheId, key1, 0, 0, 0)
|
|
#define SearchSysCacheExists2(cacheId, key1, key2) \
|
|
SearchSysCacheExists(cacheId, key1, key2, 0, 0)
|
|
#define SearchSysCacheExists3(cacheId, key1, key2, key3) \
|
|
SearchSysCacheExists(cacheId, key1, key2, key3, 0)
|
|
#define SearchSysCacheExists4(cacheId, key1, key2, key3, key4) \
|
|
SearchSysCacheExists(cacheId, key1, key2, key3, key4)
|
|
|
|
#define GetSysCacheOid1(cacheId, key1) \
|
|
GetSysCacheOid(cacheId, key1, 0, 0, 0)
|
|
#define GetSysCacheOid2(cacheId, key1, key2) \
|
|
GetSysCacheOid(cacheId, key1, key2, 0, 0)
|
|
#define GetSysCacheOid3(cacheId, key1, key2, key3) \
|
|
GetSysCacheOid(cacheId, key1, key2, key3, 0)
|
|
#define GetSysCacheOid4(cacheId, key1, key2, key3, key4) \
|
|
GetSysCacheOid(cacheId, key1, key2, key3, key4)
|
|
|
|
#define GetSysCacheHashValue1(cacheId, key1) \
|
|
GetSysCacheHashValue(cacheId, key1, 0, 0, 0)
|
|
#define GetSysCacheHashValue2(cacheId, key1, key2) \
|
|
GetSysCacheHashValue(cacheId, key1, key2, 0, 0)
|
|
#define GetSysCacheHashValue3(cacheId, key1, key2, key3) \
|
|
GetSysCacheHashValue(cacheId, key1, key2, key3, 0)
|
|
#define GetSysCacheHashValue4(cacheId, key1, key2, key3, key4) \
|
|
GetSysCacheHashValue(cacheId, key1, key2, key3, key4)
|
|
|
|
#define SearchSysCacheList1(cacheId, key1) \
|
|
SearchSysCacheList(cacheId, 1, key1, 0, 0, 0)
|
|
#define SearchSysCacheList2(cacheId, key1, key2) \
|
|
SearchSysCacheList(cacheId, 2, key1, key2, 0, 0)
|
|
#define SearchSysCacheList3(cacheId, key1, key2, key3) \
|
|
SearchSysCacheList(cacheId, 3, key1, key2, key3, 0)
|
|
#define SearchSysCacheList4(cacheId, key1, key2, key3, key4) \
|
|
SearchSysCacheList(cacheId, 4, key1, key2, key3, key4)
|
|
|
|
#define ReleaseSysCacheList(x) ReleaseCatCacheList(x)
|
|
|
|
#endif /* SYSCACHE_H */
|