mirror of
https://github.com/postgres/postgres.git
synced 2025-05-28 00:03:23 -04:00
Fix resource owner code to generate catcache and relcache leak warnings
when open references remain during normal cleanup of a resource owner. This restores the system's ability to warn about leaks to what it was before 8.0. Not really a user-level bug, but helpful for development.
This commit is contained in:
parent
6b7ef076b5
commit
08890b407e
39
src/backend/utils/cache/catcache.c
vendored
39
src/backend/utils/cache/catcache.c
vendored
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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 (cl->refcount != 0)
|
||||||
{
|
{
|
||||||
if (isCommit)
|
if (isCommit)
|
||||||
elog(WARNING, "cache reference leak: cache %s (%d), list %p has count %d",
|
PrintCatCacheListLeakWarning(cl);
|
||||||
ccp->cc_relname, ccp->id, cl, cl->refcount);
|
|
||||||
cl->refcount = 0;
|
cl->refcount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -579,10 +578,7 @@ AtEOXact_CatCache(bool isCommit)
|
|||||||
if (ct->refcount != 0)
|
if (ct->refcount != 0)
|
||||||
{
|
{
|
||||||
if (isCommit)
|
if (isCommit)
|
||||||
elog(WARNING, "cache reference leak: cache %s (%d), tuple %u has count %d",
|
PrintCatCacheLeakWarning(&ct->tuple);
|
||||||
ct->my_cache->cc_relname, ct->my_cache->id,
|
|
||||||
HeapTupleGetOid(&ct->tuple),
|
|
||||||
ct->refcount);
|
|
||||||
ct->refcount = 0;
|
ct->refcount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1807,3 +1803,32 @@ PrepareToInvalidateCacheTuple(Relation relation,
|
|||||||
ccp->cc_relisshared ? (Oid) 0 : MyDatabaseId);
|
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);
|
||||||
|
}
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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,
|
ResourceReleasePhase phase,
|
||||||
bool isCommit,
|
bool isCommit,
|
||||||
bool isTopLevel);
|
bool isTopLevel);
|
||||||
|
static void PrintRelCacheLeakWarning(Relation rel);
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
@ -231,7 +232,11 @@ ResourceOwnerReleaseInternal(ResourceOwner owner,
|
|||||||
* iterate till there are none.
|
* iterate till there are none.
|
||||||
*/
|
*/
|
||||||
while (owner->nrelrefs > 0)
|
while (owner->nrelrefs > 0)
|
||||||
|
{
|
||||||
|
if (isCommit)
|
||||||
|
PrintRelCacheLeakWarning(owner->relrefs[owner->nrelrefs - 1]);
|
||||||
RelationClose(owner->relrefs[owner->nrelrefs - 1]);
|
RelationClose(owner->relrefs[owner->nrelrefs - 1]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (phase == RESOURCE_RELEASE_LOCKS)
|
else if (phase == RESOURCE_RELEASE_LOCKS)
|
||||||
@ -284,9 +289,17 @@ ResourceOwnerReleaseInternal(ResourceOwner owner,
|
|||||||
* to iterate till there are none. Ditto for catcache lists.
|
* to iterate till there are none. Ditto for catcache lists.
|
||||||
*/
|
*/
|
||||||
while (owner->ncatrefs > 0)
|
while (owner->ncatrefs > 0)
|
||||||
|
{
|
||||||
|
if (isCommit)
|
||||||
|
PrintCatCacheLeakWarning(owner->catrefs[owner->ncatrefs - 1]);
|
||||||
ReleaseCatCache(owner->catrefs[owner->ncatrefs - 1]);
|
ReleaseCatCache(owner->catrefs[owner->ncatrefs - 1]);
|
||||||
|
}
|
||||||
while (owner->ncatlistrefs > 0)
|
while (owner->ncatlistrefs > 0)
|
||||||
|
{
|
||||||
|
if (isCommit)
|
||||||
|
PrintCatCacheListLeakWarning(owner->catlistrefs[owner->ncatlistrefs - 1]);
|
||||||
ReleaseCatCacheList(owner->catlistrefs[owner->ncatlistrefs - 1]);
|
ReleaseCatCacheList(owner->catlistrefs[owner->ncatlistrefs - 1]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* Clean up index scans too */
|
/* Clean up index scans too */
|
||||||
ReleaseResources_gist();
|
ReleaseResources_gist();
|
||||||
@ -746,3 +759,13 @@ ResourceOwnerForgetRelationRef(ResourceOwner owner, Relation rel)
|
|||||||
elog(ERROR, "relcache reference %s is not owned by resource owner %s",
|
elog(ERROR, "relcache reference %s is not owned by resource owner %s",
|
||||||
RelationGetRelationName(rel), owner->name);
|
RelationGetRelationName(rel), owner->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Debugging subroutine
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
PrintRelCacheLeakWarning(Relation rel)
|
||||||
|
{
|
||||||
|
elog(WARNING, "relcache reference leak: relation \"%s\" not closed",
|
||||||
|
RelationGetRelationName(rel));
|
||||||
|
}
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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,
|
HeapTuple tuple,
|
||||||
void (*function) (int, uint32, ItemPointer, Oid));
|
void (*function) (int, uint32, ItemPointer, Oid));
|
||||||
|
|
||||||
|
extern void PrintCatCacheLeakWarning(HeapTuple tuple);
|
||||||
|
extern void PrintCatCacheListLeakWarning(CatCList *list);
|
||||||
|
|
||||||
#endif /* CATCACHE_H */
|
#endif /* CATCACHE_H */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user