diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index cca0572..c467f11 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -728,21 +728,20 @@ InitCatCache(int id,
 			 int nkeys,
 			 const int *key,
 			 int nbuckets)
 {
 	CatCache   *cp;
 	MemoryContext oldcxt;
 	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
 	 * tables.
 	 *
 	 * If you're confused by the power-of-two check, see comments in
 	 * bitmapset.c for an explanation.
 	 */
 	Assert(nbuckets > 0 && (nbuckets & -nbuckets) == nbuckets);
@@ -769,19 +768,20 @@ InitCatCache(int id,
 		on_proc_exit(CatCachePrintStats, 0);
 #endif
 	}
 
 	/*
 	 * allocate a new cache structure
 	 *
 	 * 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
 	 * corresponding to this cache, and initialize some of the new cache's
 	 * other internal fields.  But don't open the relation yet.
 	 */
 	cp->id = id;
 	cp->cc_relname = "(not known yet)";
 	cp->cc_reloid = reloid;
@@ -808,18 +808,55 @@ InitCatCache(int id,
 	/*
 	 * back to the old context before we return...
 	 */
 	MemoryContextSwitchTo(oldcxt);
 
 	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
  *
  * This function does final initialization of a catcache: obtain the tuple
  * descriptor and set up the hash and equality function links.	We assume
  * that the relcache entry can be opened at this point!
  */
 #ifdef CACHEDEBUG
 #define CatalogCacheInitializeCache_DEBUG1 \
 	elog(DEBUG2, "CatalogCacheInitializeCache: cache @%p rel=%u", cache, \
@@ -1678,18 +1715,25 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp,
 	ct->dead = false;
 	ct->negative = negative;
 	ct->hash_value = hashValue;
 
 	dlist_push_head(&cache->cc_bucket[hashIndex], &ct->cache_elem);
 
 	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;
 }
 
 /*
  * build_dummy_tuple
  *		Generate a palloc'd HeapTuple that contains the specified key
  *		columns, and NULLs for other columns.
  *
  * This is used to store the keys for negative cache entries and CatCList
diff --git a/src/backend/utils/cache/syscache.c b/src/backend/utils/cache/syscache.c
index 1ff2f2b..e9bdfea 100644
--- a/src/backend/utils/cache/syscache.c
+++ b/src/backend/utils/cache/syscache.c
@@ -116,19 +116,19 @@ static const struct cachedesc cacheinfo[] = {
 	{AggregateRelationId,		/* AGGFNOID */
 		AggregateFnoidIndexId,
 		1,
 		{
 			Anum_pg_aggregate_aggfnoid,
 			0,
 			0,
 			0
 		},
-		32
+		16
 	},
 	{AccessMethodRelationId,	/* AMNAME */
 		AmNameIndexId,
 		1,
 		{
 			Anum_pg_am_amname,
 			0,
 			0,
 			0
@@ -171,85 +171,85 @@ static const struct cachedesc cacheinfo[] = {
 	{AccessMethodProcedureRelationId,	/* AMPROCNUM */
 		AccessMethodProcedureIndexId,
 		4,
 		{
 			Anum_pg_amproc_amprocfamily,
 			Anum_pg_amproc_amproclefttype,
 			Anum_pg_amproc_amprocrighttype,
 			Anum_pg_amproc_amprocnum
 		},
-		64
+		16
 	},
 	{AttributeRelationId,		/* ATTNAME */
 		AttributeRelidNameIndexId,
 		2,
 		{
 			Anum_pg_attribute_attrelid,
 			Anum_pg_attribute_attname,
 			0,
 			0
 		},
-		2048
+		32
 	},
 	{AttributeRelationId,		/* ATTNUM */
 		AttributeRelidNumIndexId,
 		2,
 		{
 			Anum_pg_attribute_attrelid,
 			Anum_pg_attribute_attnum,
 			0,
 			0
 		},
-		2048
+		128
 	},
 	{AuthMemRelationId,			/* AUTHMEMMEMROLE */
 		AuthMemMemRoleIndexId,
 		2,
 		{
 			Anum_pg_auth_members_member,
 			Anum_pg_auth_members_roleid,
 			0,
 			0
 		},
-		128
+		8
 	},
 	{AuthMemRelationId,			/* AUTHMEMROLEMEM */
 		AuthMemRoleMemIndexId,
 		2,
 		{
 			Anum_pg_auth_members_roleid,
 			Anum_pg_auth_members_member,
 			0,
 			0
 		},
-		128
+		8
 	},
 	{AuthIdRelationId,			/* AUTHNAME */
 		AuthIdRolnameIndexId,
 		1,
 		{
 			Anum_pg_authid_rolname,
 			0,
 			0,
 			0
 		},
-		128
+		8
 	},
 	{AuthIdRelationId,			/* AUTHOID */
 		AuthIdOidIndexId,
 		1,
 		{
 			ObjectIdAttributeNumber,
 			0,
 			0,
 			0
 		},
-		128
+		8
 	},
 	{
 		CastRelationId,			/* CASTSOURCETARGET */
 		CastSourceTargetIndexId,
 		2,
 		{
 			Anum_pg_cast_castsource,
 			Anum_pg_cast_casttarget,
 			0,
@@ -260,96 +260,96 @@ static const struct cachedesc cacheinfo[] = {
 	{OperatorClassRelationId,	/* CLAAMNAMENSP */
 		OpclassAmNameNspIndexId,
 		3,
 		{
 			Anum_pg_opclass_opcmethod,
 			Anum_pg_opclass_opcname,
 			Anum_pg_opclass_opcnamespace,
 			0
 		},
-		64
+		8
 	},
 	{OperatorClassRelationId,	/* CLAOID */
 		OpclassOidIndexId,
 		1,
 		{
 			ObjectIdAttributeNumber,
 			0,
 			0,
 			0
 		},
-		64
+		8
 	},
 	{CollationRelationId,		/* COLLNAMEENCNSP */
 		CollationNameEncNspIndexId,
 		3,
 		{
 			Anum_pg_collation_collname,
 			Anum_pg_collation_collencoding,
 			Anum_pg_collation_collnamespace,
 			0
 		},
-		64
+		8
 	},
 	{CollationRelationId,		/* COLLOID */
 		CollationOidIndexId,
 		1,
 		{
 			ObjectIdAttributeNumber,
 			0,
 			0,
 			0
 		},
-		64
+		8
 	},
 	{ConversionRelationId,		/* CONDEFAULT */
 		ConversionDefaultIndexId,
 		4,
 		{
 			Anum_pg_conversion_connamespace,
 			Anum_pg_conversion_conforencoding,
 			Anum_pg_conversion_contoencoding,
 			ObjectIdAttributeNumber,
 		},
-		128
+		8
 	},
 	{ConversionRelationId,		/* CONNAMENSP */
 		ConversionNameNspIndexId,
 		2,
 		{
 			Anum_pg_conversion_conname,
 			Anum_pg_conversion_connamespace,
 			0,
 			0
 		},
-		128
+		8
 	},
 	{ConstraintRelationId,		/* CONSTROID */
 		ConstraintOidIndexId,
 		1,
 		{
 			ObjectIdAttributeNumber,
 			0,
 			0,
 			0
 		},
-		1024
+		16
 	},
 	{ConversionRelationId,		/* CONVOID */
 		ConversionOidIndexId,
 		1,
 		{
 			ObjectIdAttributeNumber,
 			0,
 			0,
 			0
 		},
-		128
+		8
 	},
 	{DatabaseRelationId,		/* DATABASEOID */
 		DatabaseOidIndexId,
 		1,
 		{
 			ObjectIdAttributeNumber,
 			0,
 			0,
 			0
@@ -359,41 +359,41 @@ static const struct cachedesc cacheinfo[] = {
 	{DefaultAclRelationId,		/* DEFACLROLENSPOBJ */
 		DefaultAclRoleNspObjIndexId,
 		3,
 		{
 			Anum_pg_default_acl_defaclrole,
 			Anum_pg_default_acl_defaclnamespace,
 			Anum_pg_default_acl_defaclobjtype,
 			0
 		},
-		256
+		8
 	},
 	{EnumRelationId,			/* ENUMOID */
 		EnumOidIndexId,
 		1,
 		{
 			ObjectIdAttributeNumber,
 			0,
 			0,
 			0
 		},
-		256
+		8
 	},
 	{EnumRelationId,			/* ENUMTYPOIDNAME */
 		EnumTypIdLabelIndexId,
 		2,
 		{
 			Anum_pg_enum_enumtypid,
 			Anum_pg_enum_enumlabel,
 			0,
 			0
 		},
-		256
+		8
 	},
 	{EventTriggerRelationId,	/* EVENTTRIGGERNAME */
 		EventTriggerNameIndexId,
 		1,
 		{
 			Anum_pg_event_trigger_evtname,
 			0,
 			0,
 			0
@@ -414,74 +414,74 @@ static const struct cachedesc cacheinfo[] = {
 	{ForeignDataWrapperRelationId,		/* FOREIGNDATAWRAPPERNAME */
 		ForeignDataWrapperNameIndexId,
 		1,
 		{
 			Anum_pg_foreign_data_wrapper_fdwname,
 			0,
 			0,
 			0
 		},
-		8
+		2
 	},
 	{ForeignDataWrapperRelationId,		/* FOREIGNDATAWRAPPEROID */
 		ForeignDataWrapperOidIndexId,
 		1,
 		{
 			ObjectIdAttributeNumber,
 			0,
 			0,
 			0
 		},
-		8
+		2
 	},
 	{ForeignServerRelationId,	/* FOREIGNSERVERNAME */
 		ForeignServerNameIndexId,
 		1,
 		{
 			Anum_pg_foreign_server_srvname,
 			0,
 			0,
 			0
 		},
-		32
+		2
 	},
 	{ForeignServerRelationId,	/* FOREIGNSERVEROID */
 		ForeignServerOidIndexId,
 		1,
 		{
 			ObjectIdAttributeNumber,
 			0,
 			0,
 			0
 		},
-		32
+		2
 	},
 	{ForeignTableRelationId,	/* FOREIGNTABLEREL */
 		ForeignTableRelidIndexId,
 		1,
 		{
 			Anum_pg_foreign_table_ftrelid,
 			0,
 			0,
 			0
 		},
-		128
+		4
 	},
 	{IndexRelationId,			/* INDEXRELID */
 		IndexRelidIndexId,
 		1,
 		{
 			Anum_pg_index_indexrelid,
 			0,
 			0,
 			0
 		},
-		1024
+		64
 	},
 	{LanguageRelationId,		/* LANGNAME */
 		LanguageNameIndexId,
 		1,
 		{
 			Anum_pg_language_lanname,
 			0,
 			0,
 			0
@@ -502,305 +502,305 @@ static const struct cachedesc cacheinfo[] = {
 	{NamespaceRelationId,		/* NAMESPACENAME */
 		NamespaceNameIndexId,
 		1,
 		{
 			Anum_pg_namespace_nspname,
 			0,
 			0,
 			0
 		},
-		256
+		4
 	},
 	{NamespaceRelationId,		/* NAMESPACEOID */
 		NamespaceOidIndexId,
 		1,
 		{
 			ObjectIdAttributeNumber,
 			0,
 			0,
 			0
 		},
-		256
+		16
 	},
 	{OperatorRelationId,		/* OPERNAMENSP */
 		OperatorNameNspIndexId,
 		4,
 		{
 			Anum_pg_operator_oprname,
 			Anum_pg_operator_oprleft,
 			Anum_pg_operator_oprright,
 			Anum_pg_operator_oprnamespace
 		},
-		1024
+		256
 	},
 	{OperatorRelationId,		/* OPEROID */
 		OperatorOidIndexId,
 		1,
 		{
 			ObjectIdAttributeNumber,
 			0,
 			0,
 			0
 		},
-		1024
+		32
 	},
 	{OperatorFamilyRelationId,	/* OPFAMILYAMNAMENSP */
 		OpfamilyAmNameNspIndexId,
 		3,
 		{
 			Anum_pg_opfamily_opfmethod,
 			Anum_pg_opfamily_opfname,
 			Anum_pg_opfamily_opfnamespace,
 			0
 		},
-		64
+		8
 	},
 	{OperatorFamilyRelationId,	/* OPFAMILYOID */
 		OpfamilyOidIndexId,
 		1,
 		{
 			ObjectIdAttributeNumber,
 			0,
 			0,
 			0
 		},
-		64
+		8
 	},
 	{ProcedureRelationId,		/* PROCNAMEARGSNSP */
 		ProcedureNameArgsNspIndexId,
 		3,
 		{
 			Anum_pg_proc_proname,
 			Anum_pg_proc_proargtypes,
 			Anum_pg_proc_pronamespace,
 			0
 		},
-		2048
+		128
 	},
 	{ProcedureRelationId,		/* PROCOID */
 		ProcedureOidIndexId,
 		1,
 		{
 			ObjectIdAttributeNumber,
 			0,
 			0,
 			0
 		},
-		2048
+		128
 	},
 	{RangeRelationId,			/* RANGETYPE */
 		RangeTypidIndexId,
 		1,
 		{
 			Anum_pg_range_rngtypid,
 			0,
 			0,
 			0
 		},
-		64
+		4
 	},
 	{RelationRelationId,		/* RELNAMENSP */
 		ClassNameNspIndexId,
 		2,
 		{
 			Anum_pg_class_relname,
 			Anum_pg_class_relnamespace,
 			0,
 			0
 		},
-		1024
+		128
 	},
 	{RelationRelationId,		/* RELOID */
 		ClassOidIndexId,
 		1,
 		{
 			ObjectIdAttributeNumber,
 			0,
 			0,
 			0
 		},
-		1024
+		128
 	},
 	{RewriteRelationId,			/* RULERELNAME */
 		RewriteRelRulenameIndexId,
 		2,
 		{
 			Anum_pg_rewrite_ev_class,
 			Anum_pg_rewrite_rulename,
 			0,
 			0
 		},
-		1024
+		8
 	},
 	{StatisticRelationId,		/* STATRELATTINH */
 		StatisticRelidAttnumInhIndexId,
 		3,
 		{
 			Anum_pg_statistic_starelid,
 			Anum_pg_statistic_staattnum,
 			Anum_pg_statistic_stainherit,
 			0
 		},
-		1024
+		128
 	},
 	{TableSpaceRelationId,		/* TABLESPACEOID */
 		TablespaceOidIndexId,
 		1,
 		{
 			ObjectIdAttributeNumber,
 			0,
 			0,
 			0,
 		},
-		16
+		4
 	},
 	{TSConfigMapRelationId,		/* TSCONFIGMAP */
 		TSConfigMapIndexId,
 		3,
 		{
 			Anum_pg_ts_config_map_mapcfg,
 			Anum_pg_ts_config_map_maptokentype,
 			Anum_pg_ts_config_map_mapseqno,
 			0
 		},
-		4
+		2
 	},
 	{TSConfigRelationId,		/* TSCONFIGNAMENSP */
 		TSConfigNameNspIndexId,
 		2,
 		{
 			Anum_pg_ts_config_cfgname,
 			Anum_pg_ts_config_cfgnamespace,
 			0,
 			0
 		},
-		16
+		2
 	},
 	{TSConfigRelationId,		/* TSCONFIGOID */
 		TSConfigOidIndexId,
 		1,
 		{
 			ObjectIdAttributeNumber,
 			0,
 			0,
 			0
 		},
-		16
+		2
 	},
 	{TSDictionaryRelationId,	/* TSDICTNAMENSP */
 		TSDictionaryNameNspIndexId,
 		2,
 		{
 			Anum_pg_ts_dict_dictname,
 			Anum_pg_ts_dict_dictnamespace,
 			0,
 			0
 		},
-		16
+		2
 	},
 	{TSDictionaryRelationId,	/* TSDICTOID */
 		TSDictionaryOidIndexId,
 		1,
 		{
 			ObjectIdAttributeNumber,
 			0,
 			0,
 			0
 		},
-		16
+		2
 	},
 	{TSParserRelationId,		/* TSPARSERNAMENSP */
 		TSParserNameNspIndexId,
 		2,
 		{
 			Anum_pg_ts_parser_prsname,
 			Anum_pg_ts_parser_prsnamespace,
 			0,
 			0
 		},
-		4
+		2
 	},
 	{TSParserRelationId,		/* TSPARSEROID */
 		TSParserOidIndexId,
 		1,
 		{
 			ObjectIdAttributeNumber,
 			0,
 			0,
 			0
 		},
-		4
+		2
 	},
 	{TSTemplateRelationId,		/* TSTEMPLATENAMENSP */
 		TSTemplateNameNspIndexId,
 		2,
 		{
 			Anum_pg_ts_template_tmplname,
 			Anum_pg_ts_template_tmplnamespace,
 			0,
 			0
 		},
-		16
+		2
 	},
 	{TSTemplateRelationId,		/* TSTEMPLATEOID */
 		TSTemplateOidIndexId,
 		1,
 		{
 			ObjectIdAttributeNumber,
 			0,
 			0,
 			0
 		},
-		16
+		2
 	},
 	{TypeRelationId,			/* TYPENAMENSP */
 		TypeNameNspIndexId,
 		2,
 		{
 			Anum_pg_type_typname,
 			Anum_pg_type_typnamespace,
 			0,
 			0
 		},
-		1024
+		64
 	},
 	{TypeRelationId,			/* TYPEOID */
 		TypeOidIndexId,
 		1,
 		{
 			ObjectIdAttributeNumber,
 			0,
 			0,
 			0
 		},
-		1024
+		64
 	},
 	{UserMappingRelationId,		/* USERMAPPINGOID */
 		UserMappingOidIndexId,
 		1,
 		{
 			ObjectIdAttributeNumber,
 			0,
 			0,
 			0
 		},
-		128
+		2
 	},
 	{UserMappingRelationId,		/* USERMAPPINGUSERSERVER */
 		UserMappingUserServerIndexId,
 		2,
 		{
 			Anum_pg_user_mapping_umuser,
 			Anum_pg_user_mapping_umserver,
 			0,
 			0
 		},
-		128
+		2
 	}
 };
 
 static CatCache *SysCache[
 						  lengthof(cacheinfo)];
 static int	SysCacheSize = lengthof(cacheinfo);
 static bool CacheInitialized = false;
 
 static Oid SysCacheRelationOid[lengthof(cacheinfo)];
diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h
index b6e1c97..524319a 100644
--- a/src/include/utils/catcache.h
+++ b/src/include/utils/catcache.h
@@ -60,20 +60,20 @@ typedef struct catcache
 
 	/*
 	 * cc_searches - (cc_hits + cc_neg_hits + cc_newloads) is number of failed
 	 * searches, each of which will result in loading a negative entry
 	 */
 	long		cc_invals;		/* # of entries invalidated from cache */
 	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
 {
 	int			ct_magic;		/* for identifying CatCTup entries */
 #define CT_MAGIC   0x57261502
 	CatCache   *my_cache;		/* link to owning catcache */
 
 	/*
