diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2008-09-09 18:58:09 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2008-09-09 18:58:09 +0000 |
commit | ee33b95d9c2ecec170bc517783d7268a4bd0c793 (patch) | |
tree | 9012453a44799d20b15b2e4dcb1fb5e6784e2a7e /src/backend/utils/cache/inval.c | |
parent | c06629c72e7e3d435e207c2f80de3aa8a97c1d04 (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.c | 84 |
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; } |