diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c index 68995f9838..44ef1de6ee 100644 --- a/src/backend/utils/cache/catcache.c +++ b/src/backend/utils/cache/catcache.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/cache/catcache.c,v 1.118 2004/12/31 22:01:25 pgsql Exp $ + * $PostgreSQL: pgsql/src/backend/utils/cache/catcache.c,v 1.119 2005/03/25 18:30:27 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -556,8 +556,7 @@ AtEOXact_CatCache(bool isCommit) if (cl->refcount != 0) { if (isCommit) - elog(WARNING, "cache reference leak: cache %s (%d), list %p has count %d", - ccp->cc_relname, ccp->id, cl, cl->refcount); + PrintCatCacheListLeakWarning(cl); cl->refcount = 0; } @@ -579,10 +578,7 @@ AtEOXact_CatCache(bool isCommit) if (ct->refcount != 0) { if (isCommit) - elog(WARNING, "cache reference leak: cache %s (%d), tuple %u has count %d", - ct->my_cache->cc_relname, ct->my_cache->id, - HeapTupleGetOid(&ct->tuple), - ct->refcount); + PrintCatCacheLeakWarning(&ct->tuple); ct->refcount = 0; } @@ -1807,3 +1803,32 @@ PrepareToInvalidateCacheTuple(Relation relation, ccp->cc_relisshared ? (Oid) 0 : MyDatabaseId); } } + + +/* + * Subroutines for warning about reference leaks. These are exported so + * that resowner.c can call them. + */ +void +PrintCatCacheLeakWarning(HeapTuple tuple) +{ + 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); +} + +void +PrintCatCacheListLeakWarning(CatCList *list) +{ + 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); +} diff --git a/src/backend/utils/resowner/resowner.c b/src/backend/utils/resowner/resowner.c index f3063ed9d9..d533a7697f 100644 --- a/src/backend/utils/resowner/resowner.c +++ b/src/backend/utils/resowner/resowner.c @@ -14,7 +14,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/resowner/resowner.c,v 1.10 2005/03/04 20:21:06 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/resowner/resowner.c,v 1.11 2005/03/25 18:30:27 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -87,6 +87,7 @@ static void ResourceOwnerReleaseInternal(ResourceOwner owner, ResourceReleasePhase phase, bool isCommit, bool isTopLevel); +static void PrintRelCacheLeakWarning(Relation rel); /***************************************************************************** @@ -231,7 +232,11 @@ ResourceOwnerReleaseInternal(ResourceOwner owner, * iterate till there are none. */ while (owner->nrelrefs > 0) + { + if (isCommit) + PrintRelCacheLeakWarning(owner->relrefs[owner->nrelrefs - 1]); RelationClose(owner->relrefs[owner->nrelrefs - 1]); + } } } else if (phase == RESOURCE_RELEASE_LOCKS) @@ -284,9 +289,17 @@ ResourceOwnerReleaseInternal(ResourceOwner owner, * to iterate till there are none. Ditto for catcache lists. */ while (owner->ncatrefs > 0) + { + if (isCommit) + PrintCatCacheLeakWarning(owner->catrefs[owner->ncatrefs - 1]); ReleaseCatCache(owner->catrefs[owner->ncatrefs - 1]); + } while (owner->ncatlistrefs > 0) + { + if (isCommit) + PrintCatCacheListLeakWarning(owner->catlistrefs[owner->ncatlistrefs - 1]); ReleaseCatCacheList(owner->catlistrefs[owner->ncatlistrefs - 1]); + } } /* Clean up index scans too */ ReleaseResources_gist(); @@ -746,3 +759,13 @@ ResourceOwnerForgetRelationRef(ResourceOwner owner, Relation rel) elog(ERROR, "relcache reference %s is not owned by resource owner %s", RelationGetRelationName(rel), owner->name); } + +/* + * Debugging subroutine + */ +static void +PrintRelCacheLeakWarning(Relation rel) +{ + elog(WARNING, "relcache reference leak: relation \"%s\" not closed", + RelationGetRelationName(rel)); +} diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h index f08212d3f3..a9e6f19b9c 100644 --- a/src/include/utils/catcache.h +++ b/src/include/utils/catcache.h @@ -13,7 +13,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/utils/catcache.h,v 1.52 2004/12/31 22:03:45 pgsql Exp $ + * $PostgreSQL: pgsql/src/include/utils/catcache.h,v 1.53 2005/03/25 18:30:28 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -187,4 +187,7 @@ extern void PrepareToInvalidateCacheTuple(Relation relation, HeapTuple tuple, void (*function) (int, uint32, ItemPointer, Oid)); +extern void PrintCatCacheLeakWarning(HeapTuple tuple); +extern void PrintCatCacheListLeakWarning(CatCList *list); + #endif /* CATCACHE_H */