diff options
Diffstat (limited to 'src/backend/utils/cache/catcache.c')
-rw-r--r-- | src/backend/utils/cache/catcache.c | 125 |
1 files changed, 102 insertions, 23 deletions
diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c index 18db7e78e21..2e2e4d9f1f7 100644 --- a/src/backend/utils/cache/catcache.c +++ b/src/backend/utils/cache/catcache.c @@ -31,12 +31,13 @@ #endif #include "storage/lmgr.h" #include "utils/builtins.h" +#include "utils/catcache.h" #include "utils/datum.h" #include "utils/fmgroids.h" #include "utils/inval.h" #include "utils/memutils.h" #include "utils/rel.h" -#include "utils/resowner_private.h" +#include "utils/resowner.h" #include "utils/syscache.h" @@ -94,6 +95,8 @@ static CatCTup *CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, uint32 hashValue, Index hashIndex, bool negative); +static void ReleaseCatCacheWithOwner(HeapTuple tuple, ResourceOwner resowner); +static void ReleaseCatCacheListWithOwner(CatCList *list, ResourceOwner resowner); static void CatCacheFreeKeys(TupleDesc tupdesc, int nkeys, int *attnos, Datum *keys); static void CatCacheCopyKeys(TupleDesc tupdesc, int nkeys, int *attnos, @@ -104,6 +107,56 @@ static void CatCacheCopyKeys(TupleDesc tupdesc, int nkeys, int *attnos, * internal support functions */ +/* ResourceOwner callbacks to hold catcache references */ + +static void ResOwnerReleaseCatCache(Datum res); +static char *ResOwnerPrintCatCache(Datum res); +static void ResOwnerReleaseCatCacheList(Datum res); +static char *ResOwnerPrintCatCacheList(Datum res); + +static const ResourceOwnerDesc catcache_resowner_desc = +{ + /* catcache references */ + .name = "catcache reference", + .release_phase = RESOURCE_RELEASE_AFTER_LOCKS, + .release_priority = RELEASE_PRIO_CATCACHE_REFS, + .ReleaseResource = ResOwnerReleaseCatCache, + .DebugPrint = ResOwnerPrintCatCache +}; + +static const ResourceOwnerDesc catlistref_resowner_desc = +{ + /* catcache-list pins */ + .name = "catcache list reference", + .release_phase = RESOURCE_RELEASE_AFTER_LOCKS, + .release_priority = RELEASE_PRIO_CATCACHE_LIST_REFS, + .ReleaseResource = ResOwnerReleaseCatCacheList, + .DebugPrint = ResOwnerPrintCatCacheList +}; + +/* Convenience wrappers over ResourceOwnerRemember/Forget */ +static inline void +ResourceOwnerRememberCatCacheRef(ResourceOwner owner, HeapTuple tuple) +{ + ResourceOwnerRemember(owner, PointerGetDatum(tuple), &catcache_resowner_desc); +} +static inline void +ResourceOwnerForgetCatCacheRef(ResourceOwner owner, HeapTuple tuple) +{ + ResourceOwnerForget(owner, PointerGetDatum(tuple), &catcache_resowner_desc); +} +static inline void +ResourceOwnerRememberCatCacheListRef(ResourceOwner owner, CatCList *list) +{ + ResourceOwnerRemember(owner, PointerGetDatum(list), &catlistref_resowner_desc); +} +static inline void +ResourceOwnerForgetCatCacheListRef(ResourceOwner owner, CatCList *list) +{ + ResourceOwnerForget(owner, PointerGetDatum(list), &catlistref_resowner_desc); +} + + /* * Hash and equality functions for system types that are used as cache key * fields. In some cases, we just call the regular SQL-callable functions for @@ -1268,7 +1321,7 @@ SearchCatCacheInternal(CatCache *cache, */ if (!ct->negative) { - ResourceOwnerEnlargeCatCacheRefs(CurrentResourceOwner); + ResourceOwnerEnlarge(CurrentResourceOwner); ct->refcount++; ResourceOwnerRememberCatCacheRef(CurrentResourceOwner, &ct->tuple); @@ -1369,7 +1422,7 @@ SearchCatCacheMiss(CatCache *cache, hashValue, hashIndex, false); /* immediately set the refcount to 1 */ - ResourceOwnerEnlargeCatCacheRefs(CurrentResourceOwner); + ResourceOwnerEnlarge(CurrentResourceOwner); ct->refcount++; ResourceOwnerRememberCatCacheRef(CurrentResourceOwner, &ct->tuple); break; /* assume only one match */ @@ -1437,6 +1490,12 @@ SearchCatCacheMiss(CatCache *cache, void ReleaseCatCache(HeapTuple tuple) { + ReleaseCatCacheWithOwner(tuple, CurrentResourceOwner); +} + +static void +ReleaseCatCacheWithOwner(HeapTuple tuple, ResourceOwner resowner) +{ CatCTup *ct = (CatCTup *) (((char *) tuple) - offsetof(CatCTup, tuple)); @@ -1445,7 +1504,8 @@ ReleaseCatCache(HeapTuple tuple) Assert(ct->refcount > 0); ct->refcount--; - ResourceOwnerForgetCatCacheRef(CurrentResourceOwner, &ct->tuple); + if (resowner) + ResourceOwnerForgetCatCacheRef(CurrentResourceOwner, &ct->tuple); if ( #ifndef CATCACHE_FORCE_RELEASE @@ -1581,7 +1641,7 @@ SearchCatCacheList(CatCache *cache, dlist_move_head(&cache->cc_lists, &cl->cache_elem); /* Bump the list's refcount and return it */ - ResourceOwnerEnlargeCatCacheListRefs(CurrentResourceOwner); + ResourceOwnerEnlarge(CurrentResourceOwner); cl->refcount++; ResourceOwnerRememberCatCacheListRef(CurrentResourceOwner, cl); @@ -1693,7 +1753,7 @@ SearchCatCacheList(CatCache *cache, table_close(relation, AccessShareLock); /* Make sure the resource owner has room to remember this entry. */ - ResourceOwnerEnlargeCatCacheListRefs(CurrentResourceOwner); + ResourceOwnerEnlarge(CurrentResourceOwner); /* Now we can build the CatCList entry. */ oldcxt = MemoryContextSwitchTo(CacheMemoryContext); @@ -1779,11 +1839,18 @@ SearchCatCacheList(CatCache *cache, void ReleaseCatCacheList(CatCList *list) { + ReleaseCatCacheListWithOwner(list, CurrentResourceOwner); +} + +static void +ReleaseCatCacheListWithOwner(CatCList *list, ResourceOwner resowner) +{ /* Safety checks to ensure we were handed a cache entry */ Assert(list->cl_magic == CL_MAGIC); Assert(list->refcount > 0); list->refcount--; - ResourceOwnerForgetCatCacheListRef(CurrentResourceOwner, list); + if (resowner) + ResourceOwnerForgetCatCacheListRef(CurrentResourceOwner, list); if ( #ifndef CATCACHE_FORCE_RELEASE @@ -2059,31 +2126,43 @@ PrepareToInvalidateCacheTuple(Relation relation, } } +/* ResourceOwner callbacks */ -/* - * Subroutines for warning about reference leaks. These are exported so - * that resowner.c can call them. - */ -void -PrintCatCacheLeakWarning(HeapTuple tuple) +static void +ResOwnerReleaseCatCache(Datum res) { + ReleaseCatCacheWithOwner((HeapTuple) DatumGetPointer(res), NULL); +} + +static char * +ResOwnerPrintCatCache(Datum res) +{ + HeapTuple tuple = (HeapTuple) DatumGetPointer(res); CatCTup *ct = (CatCTup *) (((char *) tuple) - offsetof(CatCTup, tuple)); /* Safety check to ensure we were handed a cache entry */ Assert(ct->ct_magic == CT_MAGIC); - elog(WARNING, "cache reference leak: cache %s (%d), tuple %u/%u has count %d", - ct->my_cache->cc_relname, ct->my_cache->id, - ItemPointerGetBlockNumber(&(tuple->t_self)), - ItemPointerGetOffsetNumber(&(tuple->t_self)), - ct->refcount); + return psprintf("cache %s (%d), tuple %u/%u has count %d", + ct->my_cache->cc_relname, ct->my_cache->id, + ItemPointerGetBlockNumber(&(tuple->t_self)), + ItemPointerGetOffsetNumber(&(tuple->t_self)), + ct->refcount); } -void -PrintCatCacheListLeakWarning(CatCList *list) +static void +ResOwnerReleaseCatCacheList(Datum res) { - elog(WARNING, "cache reference leak: cache %s (%d), list %p has count %d", - list->my_cache->cc_relname, list->my_cache->id, - list, list->refcount); + ReleaseCatCacheListWithOwner((CatCList *) DatumGetPointer(res), NULL); +} + +static char * +ResOwnerPrintCatCacheList(Datum res) +{ + CatCList *list = (CatCList *) DatumGetPointer(res); + + return psprintf("cache %s (%d), list %p has count %d", + list->my_cache->cc_relname, list->my_cache->id, + list, list->refcount); } |