]> granicus.if.org Git - postgresql/commitdiff
Make catalog cache hash tables resizeable.
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Thu, 5 Sep 2013 16:47:56 +0000 (19:47 +0300)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Thu, 5 Sep 2013 17:20:03 +0000 (20:20 +0300)
If the hash table backing a catalog cache becomes too full (fillfactor > 2),
enlarge it. A new buckets array, double the size of the old, is allocated,
and all entries in the old hash are moved to the right bucket in the new
hash.

This has two benefits. First, cache lookups don't get so expensive when
there are lots of entries in a cache, like if you access hundreds of
thousands of tables. Second, we can make the (initial) sizes of the caches
much smaller, which saves memory.

This patch dials down the initial sizes of the catcaches. The new sizes are
chosen so that a backend that only runs a few basic queries still won't need
to enlarge any of them.

src/backend/utils/cache/catcache.c
src/backend/utils/cache/syscache.c
src/include/utils/catcache.h

index cca0572a5dc00a87ab7b0aff5cce4400d19af715..c467f11ac8bb6cca385910c050b13d33e94cb258 100644 (file)
@@ -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;
 }
 
index 1ff2f2b5af015cb36e262d447decde5722b42b06..e9bdfeae213dc9727b0a21a7f2657e95419c30b9 100644 (file)
@@ -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
        }
 };
 
index b6e1c97982dfbaffd788fee13c51998a2c6d2691..524319aad96e0b4f4339e20b8ba82f5de78cfa13 100644 (file)
@@ -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