diff --git a/src/backend/utils/cache/inval.c b/src/backend/utils/cache/inval.c
index 347fdde..6714a30 100644
*** a/src/backend/utils/cache/inval.c
--- b/src/backend/utils/cache/inval.c
*************** static int	maxSharedInvalidMessagesArray
*** 178,195 ****
  /*
   * Dynamically-registered callback functions.  Current implementation
   * assumes there won't be very many of these at once; could improve if needed.
   */
  
! #define MAX_SYSCACHE_CALLBACKS 32
  #define MAX_RELCACHE_CALLBACKS 10
  
  static struct SYSCACHECALLBACK
  {
  	int16		id;				/* cache number */
  	SyscacheCallbackFunction function;
  	Datum		arg;
  }	syscache_callback_list[MAX_SYSCACHE_CALLBACKS];
  
  static int	syscache_callback_count = 0;
  
  static struct RELCACHECALLBACK
--- 178,202 ----
  /*
   * Dynamically-registered callback functions.  Current implementation
   * assumes there won't be very many of these at once; could improve if needed.
+  *
+  * To avoid searching in CallSyscacheCallbacks, all callbacks for a given
+  * syscache are linked into a list pointed to by syscache_callback_links[id].
+  * The link values are syscache_callback_list[] index plus 1, or 0 for none.
   */
  
! #define MAX_SYSCACHE_CALLBACKS 64
  #define MAX_RELCACHE_CALLBACKS 10
  
  static struct SYSCACHECALLBACK
  {
  	int16		id;				/* cache number */
+ 	int16		link;			/* next callback index+1 for same cache */
  	SyscacheCallbackFunction function;
  	Datum		arg;
  }	syscache_callback_list[MAX_SYSCACHE_CALLBACKS];
  
+ static int16 syscache_callback_links[SysCacheSize];
+ 
  static int	syscache_callback_count = 0;
  
  static struct RELCACHECALLBACK
*************** CacheRegisterSyscacheCallback(int cachei
*** 1386,1392 ****
--- 1393,1417 ----
  	if (syscache_callback_count >= MAX_SYSCACHE_CALLBACKS)
  		elog(FATAL, "out of syscache_callback_list slots");
  
+ 	Assert(cacheid >= 0 && cacheid < SysCacheSize);
+ 
+ 	if (syscache_callback_links[cacheid] == 0)
+ 	{
+ 		/* first callback for this cache */
+ 		syscache_callback_links[cacheid] = syscache_callback_count + 1;
+ 	}
+ 	else
+ 	{
+ 		/* add to end of chain, so that older callbacks are called first */
+ 		int			i = syscache_callback_links[cacheid] - 1;
+ 
+ 		while (syscache_callback_list[i].link > 0)
+ 			i = syscache_callback_list[i].link - 1;
+ 		syscache_callback_list[i].link = syscache_callback_count + 1;
+ 	}
+ 
  	syscache_callback_list[syscache_callback_count].id = cacheid;
+ 	syscache_callback_list[syscache_callback_count].link = 0;
  	syscache_callback_list[syscache_callback_count].function = func;
  	syscache_callback_list[syscache_callback_count].arg = arg;
  
*************** CallSyscacheCallbacks(int cacheid, uint3
*** 1426,1436 ****
  {
  	int			i;
  
! 	for (i = 0; i < syscache_callback_count; i++)
  	{
  		struct SYSCACHECALLBACK *ccitem = syscache_callback_list + i;
  
! 		if (ccitem->id == cacheid)
! 			(*ccitem->function) (ccitem->arg, cacheid, hashvalue);
  	}
  }
--- 1451,1464 ----
  {
  	int			i;
  
! 	Assert(cacheid >= 0 && cacheid < SysCacheSize);
! 	i = syscache_callback_links[cacheid] - 1;
! 	while (i >= 0)
  	{
  		struct SYSCACHECALLBACK *ccitem = syscache_callback_list + i;
  
! 		Assert(ccitem->id == cacheid);
! 		(*ccitem->function) (ccitem->arg, cacheid, hashvalue);
! 		i = ccitem->link - 1;
  	}
  }
diff --git a/src/backend/utils/cache/syscache.c b/src/backend/utils/cache/syscache.c
index 066ce72..f0a16e3 100644
*** a/src/backend/utils/cache/syscache.c
--- b/src/backend/utils/cache/syscache.c
*************** static const struct cachedesc cacheinfo[
*** 971,978 ****
  	}
  };
  
- #define SysCacheSize	((int) lengthof(cacheinfo))
- 
  static CatCache *SysCache[SysCacheSize];
  
  static bool CacheInitialized = false;
--- 971,976 ----
*************** InitCatalogCache(void)
*** 1003,1008 ****
--- 1001,1009 ----
  	int			i,
  				j;
  
+ 	StaticAssertStmt(SysCacheSize == (int) lengthof(cacheinfo),
+ 					 "SysCacheSize does not match syscache.c's array");
+ 
  	Assert(!CacheInitialized);
  
  	SysCacheRelationOidSize = SysCacheSupportingRelOidSize = 0;
diff --git a/src/include/utils/syscache.h b/src/include/utils/syscache.h
index 73991dd..e20284d 100644
*** a/src/include/utils/syscache.h
--- b/src/include/utils/syscache.h
*************** enum SysCacheIdentifier
*** 108,113 ****
--- 108,115 ----
  	TYPEOID,
  	USERMAPPINGOID,
  	USERMAPPINGUSERSERVER
+ 
+ #define SysCacheSize (USERMAPPINGUSERSERVER + 1)
  };
  
  extern void InitCatalogCache(void);
