summaryrefslogtreecommitdiff
path: root/src/backend/utils/cache/inval.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2008-09-09 18:58:09 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2008-09-09 18:58:09 +0000
commitee33b95d9c2ecec170bc517783d7268a4bd0c793 (patch)
tree9012453a44799d20b15b2e4dcb1fb5e6784e2a7e /src/backend/utils/cache/inval.c
parentc06629c72e7e3d435e207c2f80de3aa8a97c1d04 (diff)
Improve the plan cache invalidation mechanism to make it invalidate plans
when user-defined functions used in a plan are modified. Also invalidate plans when schemas, operators, or operator classes are modified; but for these cases we just invalidate everything rather than tracking exact dependencies, since these types of objects seldom change in a production database. Tom Lane; loosely based on a patch by Martin Pihlak.
Diffstat (limited to 'src/backend/utils/cache/inval.c')
-rw-r--r--src/backend/utils/cache/inval.c84
1 files changed, 49 insertions, 35 deletions
diff --git a/src/backend/utils/cache/inval.c b/src/backend/utils/cache/inval.c
index 050d7cc88de..5c9451022d2 100644
--- a/src/backend/utils/cache/inval.c
+++ b/src/backend/utils/cache/inval.c
@@ -80,7 +80,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/cache/inval.c,v 1.86 2008/06/19 21:32:56 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/cache/inval.c,v 1.87 2008/09/09 18:58:08 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -160,16 +160,25 @@ static TransInvalidationInfo *transInvalInfo = NULL;
* assumes there won't be very many of these at once; could improve if needed.
*/
-#define MAX_CACHE_CALLBACKS 20
+#define MAX_SYSCACHE_CALLBACKS 20
+#define MAX_RELCACHE_CALLBACKS 5
-static struct CACHECALLBACK
+static struct SYSCACHECALLBACK
{
- int16 id; /* cache number or message type id */
- CacheCallbackFunction function;
+ int16 id; /* cache number */
+ SyscacheCallbackFunction function;
Datum arg;
-} cache_callback_list[MAX_CACHE_CALLBACKS];
+} syscache_callback_list[MAX_SYSCACHE_CALLBACKS];
-static int cache_callback_count = 0;
+static int syscache_callback_count = 0;
+
+static struct RELCACHECALLBACK
+{
+ RelcacheCallbackFunction function;
+ Datum arg;
+} relcache_callback_list[MAX_RELCACHE_CALLBACKS];
+
+static int relcache_callback_count = 0;
/* info values for 2PC callback */
#define TWOPHASE_INFO_MSG 0 /* SharedInvalidationMessage */
@@ -484,12 +493,13 @@ LocalExecuteInvalidationMessage(SharedInvalidationMessage *msg)
msg->cc.hashValue,
&msg->cc.tuplePtr);
- for (i = 0; i < cache_callback_count; i++)
+ for (i = 0; i < syscache_callback_count; i++)
{
- struct CACHECALLBACK *ccitem = cache_callback_list + i;
+ struct SYSCACHECALLBACK *ccitem = syscache_callback_list + i;
if (ccitem->id == msg->cc.id)
- (*ccitem->function) (ccitem->arg, InvalidOid);
+ (*ccitem->function) (ccitem->arg,
+ msg->cc.id, &msg->cc.tuplePtr);
}
}
}
@@ -499,12 +509,11 @@ LocalExecuteInvalidationMessage(SharedInvalidationMessage *msg)
{
RelationCacheInvalidateEntry(msg->rc.relId);
- for (i = 0; i < cache_callback_count; i++)
+ for (i = 0; i < relcache_callback_count; i++)
{
- struct CACHECALLBACK *ccitem = cache_callback_list + i;
+ struct RELCACHECALLBACK *ccitem = relcache_callback_list + i;
- if (ccitem->id == SHAREDINVALRELCACHE_ID)
- (*ccitem->function) (ccitem->arg, msg->rc.relId);
+ (*ccitem->function) (ccitem->arg, msg->rc.relId);
}
}
}
@@ -539,9 +548,16 @@ InvalidateSystemCaches(void)
ResetCatalogCaches();
RelationCacheInvalidate(); /* gets smgr cache too */
- for (i = 0; i < cache_callback_count; i++)
+ for (i = 0; i < syscache_callback_count; i++)
{
- struct CACHECALLBACK *ccitem = cache_callback_list + i;
+ struct SYSCACHECALLBACK *ccitem = syscache_callback_list + i;
+
+ (*ccitem->function) (ccitem->arg, ccitem->id, NULL);
+ }
+
+ for (i = 0; i < relcache_callback_count; i++)
+ {
+ struct RELCACHECALLBACK *ccitem = relcache_callback_list + i;
(*ccitem->function) (ccitem->arg, InvalidOid);
}
@@ -1177,26 +1193,25 @@ CacheInvalidateRelcacheByRelid(Oid relid)
/*
* CacheRegisterSyscacheCallback
* Register the specified function to be called for all future
- * invalidation events in the specified cache.
+ * invalidation events in the specified cache. The cache ID and the
+ * TID of the tuple being invalidated will be passed to the function.
*
- * NOTE: currently, the OID argument to the callback routine is not
- * provided for syscache callbacks; the routine doesn't really get any
- * useful info as to exactly what changed. It should treat every call
- * as a "cache flush" request.
+ * NOTE: NULL will be passed for the TID if a cache reset request is received.
+ * In this case the called routines should flush all cached state.
*/
void
CacheRegisterSyscacheCallback(int cacheid,
- CacheCallbackFunction func,
+ SyscacheCallbackFunction func,
Datum arg)
{
- if (cache_callback_count >= MAX_CACHE_CALLBACKS)
- elog(FATAL, "out of cache_callback_list slots");
+ if (syscache_callback_count >= MAX_SYSCACHE_CALLBACKS)
+ elog(FATAL, "out of syscache_callback_list slots");
- cache_callback_list[cache_callback_count].id = cacheid;
- cache_callback_list[cache_callback_count].function = func;
- cache_callback_list[cache_callback_count].arg = arg;
+ syscache_callback_list[syscache_callback_count].id = cacheid;
+ syscache_callback_list[syscache_callback_count].function = func;
+ syscache_callback_list[syscache_callback_count].arg = arg;
- ++cache_callback_count;
+ ++syscache_callback_count;
}
/*
@@ -1209,15 +1224,14 @@ CacheRegisterSyscacheCallback(int cacheid,
* In this case the called routines should flush all cached state.
*/
void
-CacheRegisterRelcacheCallback(CacheCallbackFunction func,
+CacheRegisterRelcacheCallback(RelcacheCallbackFunction func,
Datum arg)
{
- if (cache_callback_count >= MAX_CACHE_CALLBACKS)
- elog(FATAL, "out of cache_callback_list slots");
+ if (relcache_callback_count >= MAX_RELCACHE_CALLBACKS)
+ elog(FATAL, "out of relcache_callback_list slots");
- cache_callback_list[cache_callback_count].id = SHAREDINVALRELCACHE_ID;
- cache_callback_list[cache_callback_count].function = func;
- cache_callback_list[cache_callback_count].arg = arg;
+ relcache_callback_list[relcache_callback_count].function = func;
+ relcache_callback_list[relcache_callback_count].arg = arg;
- ++cache_callback_count;
+ ++relcache_callback_count;
}