diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c index cca0572a5d..c467f11ac8 100644 --- a/src/backend/utils/cache/catcache.c +++ b/src/backend/utils/cache/catcache.c @@ -734,9 +734,8 @@ InitCatCache(int id, int i; /* - * nbuckets is the number of hash buckets to use in this catcache. - * Currently we just use a hard-wired estimate of an appropriate size for - * each cache; maybe later make them dynamically resizable? + * nbuckets is the initial number of hash buckets to use in this catcache. + * It will be enlarged later if it becomes too full. * * nbuckets must be a power of two. We check this via Assert rather than * a full runtime check because the values will be coming from constant @@ -775,7 +774,8 @@ InitCatCache(int id, * * Note: we rely on zeroing to initialize all the dlist headers correctly */ - cp = (CatCache *) palloc0(sizeof(CatCache) + nbuckets * sizeof(dlist_head)); + cp = (CatCache *) palloc0(sizeof(CatCache)); + cp->cc_bucket = palloc0(nbuckets * sizeof(dlist_head)); /* * initialize the cache's relation information for the relation @@ -813,6 +813,43 @@ InitCatCache(int id, return cp; } +/* + * Enlarge a catcache, doubling the number of buckets. + */ +static void +RehashCatCache(CatCache *cp) +{ + dlist_head *newbucket; + int newnbuckets; + int i; + + elog(DEBUG1, "rehashing catalog cache id %d for %s; %d tups, %d buckets", + cp->id, cp->cc_relname, cp->cc_ntup, cp->cc_nbuckets); + + /* Allocate a new, larger, hash table. */ + newnbuckets = cp->cc_nbuckets * 2; + newbucket = (dlist_head *) MemoryContextAllocZero(CacheMemoryContext, newnbuckets * sizeof(dlist_head)); + + /* Move all entries from old hash table to new. */ + for (i = 0; i < cp->cc_nbuckets; i++) + { + dlist_mutable_iter iter; + dlist_foreach_modify(iter, &cp->cc_bucket[i]) + { + CatCTup *ct = dlist_container(CatCTup, cache_elem, iter.cur); + int hashIndex = HASH_INDEX(ct->hash_value, newnbuckets); + + dlist_delete(iter.cur); + dlist_push_head(&newbucket[hashIndex], &ct->cache_elem); + } + } + + /* Switch to the new array. */ + pfree(cp->cc_bucket); + cp->cc_nbuckets = newnbuckets; + cp->cc_bucket = newbucket; +} + /* * CatalogCacheInitializeCache * @@ -1684,6 +1721,13 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, cache->cc_ntup++; CacheHdr->ch_ntup++; + /* + * If the hash table has become too full, enlarge the buckets array. + * Quite arbitrarily, we enlarge when fill factor > 2. + */ + if (cache->cc_ntup > cache->cc_nbuckets * 2) + RehashCatCache(cache); + return ct; } diff --git a/src/backend/utils/cache/syscache.c b/src/backend/utils/cache/syscache.c index 1ff2f2b5af..e9bdfeae21 100644 --- a/src/backend/utils/cache/syscache.c +++ b/src/backend/utils/cache/syscache.c @@ -122,7 +122,7 @@ static const struct cachedesc cacheinfo[] = { 0, 0 }, - 32 + 16 }, {AccessMethodRelationId, /* AMNAME */ AmNameIndexId, @@ -177,7 +177,7 @@ static const struct cachedesc cacheinfo[] = { Anum_pg_amproc_amprocrighttype, Anum_pg_amproc_amprocnum }, - 64 + 16 }, {AttributeRelationId, /* ATTNAME */ AttributeRelidNameIndexId, @@ -188,7 +188,7 @@ static const struct cachedesc cacheinfo[] = { 0, 0 }, - 2048 + 32 }, {AttributeRelationId, /* ATTNUM */ AttributeRelidNumIndexId, @@ -199,7 +199,7 @@ static const struct cachedesc cacheinfo[] = { 0, 0 }, - 2048 + 128 }, {AuthMemRelationId, /* AUTHMEMMEMROLE */ AuthMemMemRoleIndexId, @@ -210,7 +210,7 @@ static const struct cachedesc cacheinfo[] = { 0, 0 }, - 128 + 8 }, {AuthMemRelationId, /* AUTHMEMROLEMEM */ AuthMemRoleMemIndexId, @@ -221,7 +221,7 @@ static const struct cachedesc cacheinfo[] = { 0, 0 }, - 128 + 8 }, {AuthIdRelationId, /* AUTHNAME */ AuthIdRolnameIndexId, @@ -232,7 +232,7 @@ static const struct cachedesc cacheinfo[] = { 0, 0 }, - 128 + 8 }, {AuthIdRelationId, /* AUTHOID */ AuthIdOidIndexId, @@ -243,7 +243,7 @@ static const struct cachedesc cacheinfo[] = { 0, 0 }, - 128 + 8 }, { CastRelationId, /* CASTSOURCETARGET */ @@ -266,7 +266,7 @@ static const struct cachedesc cacheinfo[] = { Anum_pg_opclass_opcnamespace, 0 }, - 64 + 8 }, {OperatorClassRelationId, /* CLAOID */ OpclassOidIndexId, @@ -277,7 +277,7 @@ static const struct cachedesc cacheinfo[] = { 0, 0 }, - 64 + 8 }, {CollationRelationId, /* COLLNAMEENCNSP */ CollationNameEncNspIndexId, @@ -288,7 +288,7 @@ static const struct cachedesc cacheinfo[] = { Anum_pg_collation_collnamespace, 0 }, - 64 + 8 }, {CollationRelationId, /* COLLOID */ CollationOidIndexId, @@ -299,7 +299,7 @@ static const struct cachedesc cacheinfo[] = { 0, 0 }, - 64 + 8 }, {ConversionRelationId, /* CONDEFAULT */ ConversionDefaultIndexId, @@ -310,7 +310,7 @@ static const struct cachedesc cacheinfo[] = { Anum_pg_conversion_contoencoding, ObjectIdAttributeNumber, }, - 128 + 8 }, {ConversionRelationId, /* CONNAMENSP */ ConversionNameNspIndexId, @@ -321,7 +321,7 @@ static const struct cachedesc cacheinfo[] = { 0, 0 }, - 128 + 8 }, {ConstraintRelationId, /* CONSTROID */ ConstraintOidIndexId, @@ -332,7 +332,7 @@ static const struct cachedesc cacheinfo[] = { 0, 0 }, - 1024 + 16 }, {ConversionRelationId, /* CONVOID */ ConversionOidIndexId, @@ -343,7 +343,7 @@ static const struct cachedesc cacheinfo[] = { 0, 0 }, - 128 + 8 }, {DatabaseRelationId, /* DATABASEOID */ DatabaseOidIndexId, @@ -365,7 +365,7 @@ static const struct cachedesc cacheinfo[] = { Anum_pg_default_acl_defaclobjtype, 0 }, - 256 + 8 }, {EnumRelationId, /* ENUMOID */ EnumOidIndexId, @@ -376,7 +376,7 @@ static const struct cachedesc cacheinfo[] = { 0, 0 }, - 256 + 8 }, {EnumRelationId, /* ENUMTYPOIDNAME */ EnumTypIdLabelIndexId, @@ -387,7 +387,7 @@ static const struct cachedesc cacheinfo[] = { 0, 0 }, - 256 + 8 }, {EventTriggerRelationId, /* EVENTTRIGGERNAME */ EventTriggerNameIndexId, @@ -420,7 +420,7 @@ static const struct cachedesc cacheinfo[] = { 0, 0 }, - 8 + 2 }, {ForeignDataWrapperRelationId, /* FOREIGNDATAWRAPPEROID */ ForeignDataWrapperOidIndexId, @@ -431,7 +431,7 @@ static const struct cachedesc cacheinfo[] = { 0, 0 }, - 8 + 2 }, {ForeignServerRelationId, /* FOREIGNSERVERNAME */ ForeignServerNameIndexId, @@ -442,7 +442,7 @@ static const struct cachedesc cacheinfo[] = { 0, 0 }, - 32 + 2 }, {ForeignServerRelationId, /* FOREIGNSERVEROID */ ForeignServerOidIndexId, @@ -453,7 +453,7 @@ static const struct cachedesc cacheinfo[] = { 0, 0 }, - 32 + 2 }, {ForeignTableRelationId, /* FOREIGNTABLEREL */ ForeignTableRelidIndexId, @@ -464,7 +464,7 @@ static const struct cachedesc cacheinfo[] = { 0, 0 }, - 128 + 4 }, {IndexRelationId, /* INDEXRELID */ IndexRelidIndexId, @@ -475,7 +475,7 @@ static const struct cachedesc cacheinfo[] = { 0, 0 }, - 1024 + 64 }, {LanguageRelationId, /* LANGNAME */ LanguageNameIndexId, @@ -508,7 +508,7 @@ static const struct cachedesc cacheinfo[] = { 0, 0 }, - 256 + 4 }, {NamespaceRelationId, /* NAMESPACEOID */ NamespaceOidIndexId, @@ -519,7 +519,7 @@ static const struct cachedesc cacheinfo[] = { 0, 0 }, - 256 + 16 }, {OperatorRelationId, /* OPERNAMENSP */ OperatorNameNspIndexId, @@ -530,7 +530,7 @@ static const struct cachedesc cacheinfo[] = { Anum_pg_operator_oprright, Anum_pg_operator_oprnamespace }, - 1024 + 256 }, {OperatorRelationId, /* OPEROID */ OperatorOidIndexId, @@ -541,7 +541,7 @@ static const struct cachedesc cacheinfo[] = { 0, 0 }, - 1024 + 32 }, {OperatorFamilyRelationId, /* OPFAMILYAMNAMENSP */ OpfamilyAmNameNspIndexId, @@ -552,7 +552,7 @@ static const struct cachedesc cacheinfo[] = { Anum_pg_opfamily_opfnamespace, 0 }, - 64 + 8 }, {OperatorFamilyRelationId, /* OPFAMILYOID */ OpfamilyOidIndexId, @@ -563,7 +563,7 @@ static const struct cachedesc cacheinfo[] = { 0, 0 }, - 64 + 8 }, {ProcedureRelationId, /* PROCNAMEARGSNSP */ ProcedureNameArgsNspIndexId, @@ -574,7 +574,7 @@ static const struct cachedesc cacheinfo[] = { Anum_pg_proc_pronamespace, 0 }, - 2048 + 128 }, {ProcedureRelationId, /* PROCOID */ ProcedureOidIndexId, @@ -585,7 +585,7 @@ static const struct cachedesc cacheinfo[] = { 0, 0 }, - 2048 + 128 }, {RangeRelationId, /* RANGETYPE */ RangeTypidIndexId, @@ -596,7 +596,7 @@ static const struct cachedesc cacheinfo[] = { 0, 0 }, - 64 + 4 }, {RelationRelationId, /* RELNAMENSP */ ClassNameNspIndexId, @@ -607,7 +607,7 @@ static const struct cachedesc cacheinfo[] = { 0, 0 }, - 1024 + 128 }, {RelationRelationId, /* RELOID */ ClassOidIndexId, @@ -618,7 +618,7 @@ static const struct cachedesc cacheinfo[] = { 0, 0 }, - 1024 + 128 }, {RewriteRelationId, /* RULERELNAME */ RewriteRelRulenameIndexId, @@ -629,7 +629,7 @@ static const struct cachedesc cacheinfo[] = { 0, 0 }, - 1024 + 8 }, {StatisticRelationId, /* STATRELATTINH */ StatisticRelidAttnumInhIndexId, @@ -640,7 +640,7 @@ static const struct cachedesc cacheinfo[] = { Anum_pg_statistic_stainherit, 0 }, - 1024 + 128 }, {TableSpaceRelationId, /* TABLESPACEOID */ TablespaceOidIndexId, @@ -651,7 +651,7 @@ static const struct cachedesc cacheinfo[] = { 0, 0, }, - 16 + 4 }, {TSConfigMapRelationId, /* TSCONFIGMAP */ TSConfigMapIndexId, @@ -662,7 +662,7 @@ static const struct cachedesc cacheinfo[] = { Anum_pg_ts_config_map_mapseqno, 0 }, - 4 + 2 }, {TSConfigRelationId, /* TSCONFIGNAMENSP */ TSConfigNameNspIndexId, @@ -673,7 +673,7 @@ static const struct cachedesc cacheinfo[] = { 0, 0 }, - 16 + 2 }, {TSConfigRelationId, /* TSCONFIGOID */ TSConfigOidIndexId, @@ -684,7 +684,7 @@ static const struct cachedesc cacheinfo[] = { 0, 0 }, - 16 + 2 }, {TSDictionaryRelationId, /* TSDICTNAMENSP */ TSDictionaryNameNspIndexId, @@ -695,7 +695,7 @@ static const struct cachedesc cacheinfo[] = { 0, 0 }, - 16 + 2 }, {TSDictionaryRelationId, /* TSDICTOID */ TSDictionaryOidIndexId, @@ -706,7 +706,7 @@ static const struct cachedesc cacheinfo[] = { 0, 0 }, - 16 + 2 }, {TSParserRelationId, /* TSPARSERNAMENSP */ TSParserNameNspIndexId, @@ -717,7 +717,7 @@ static const struct cachedesc cacheinfo[] = { 0, 0 }, - 4 + 2 }, {TSParserRelationId, /* TSPARSEROID */ TSParserOidIndexId, @@ -728,7 +728,7 @@ static const struct cachedesc cacheinfo[] = { 0, 0 }, - 4 + 2 }, {TSTemplateRelationId, /* TSTEMPLATENAMENSP */ TSTemplateNameNspIndexId, @@ -739,7 +739,7 @@ static const struct cachedesc cacheinfo[] = { 0, 0 }, - 16 + 2 }, {TSTemplateRelationId, /* TSTEMPLATEOID */ TSTemplateOidIndexId, @@ -750,7 +750,7 @@ static const struct cachedesc cacheinfo[] = { 0, 0 }, - 16 + 2 }, {TypeRelationId, /* TYPENAMENSP */ TypeNameNspIndexId, @@ -761,7 +761,7 @@ static const struct cachedesc cacheinfo[] = { 0, 0 }, - 1024 + 64 }, {TypeRelationId, /* TYPEOID */ TypeOidIndexId, @@ -772,7 +772,7 @@ static const struct cachedesc cacheinfo[] = { 0, 0 }, - 1024 + 64 }, {UserMappingRelationId, /* USERMAPPINGOID */ UserMappingOidIndexId, @@ -783,7 +783,7 @@ static const struct cachedesc cacheinfo[] = { 0, 0 }, - 128 + 2 }, {UserMappingRelationId, /* USERMAPPINGUSERSERVER */ UserMappingUserServerIndexId, @@ -794,7 +794,7 @@ static const struct cachedesc cacheinfo[] = { 0, 0 }, - 128 + 2 } }; diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h index b6e1c97982..524319aad9 100644 --- a/src/include/utils/catcache.h +++ b/src/include/utils/catcache.h @@ -66,8 +66,8 @@ typedef struct catcache long cc_lsearches; /* total # list-searches */ long cc_lhits; /* # of matches against existing lists */ #endif - dlist_head cc_bucket[1]; /* hash buckets --- VARIABLE LENGTH ARRAY */ -} CatCache; /* VARIABLE LENGTH STRUCT */ + dlist_head *cc_bucket; /* hash buckets */ +} CatCache; typedef struct catctup