mirror of
https://github.com/postgres/postgres.git
synced 2025-04-24 10:47:04 +03:00
During CatCacheRemoveCList, we must now remove any members that are
dead and have become unreferenced. Before 8.1, such members were left for AtEOXact_CatCache() to clean up, but now AtEOXact_CatCache isn't supposed to have anything to do. In an assert-enabled build this bug leads to an assertion failure at transaction end, but in a non-assert build the dead member is effectively just a small memory leak. Per report from Jeremy Drake.
This commit is contained in:
parent
0a8510e0f8
commit
7eb5428199
20
src/backend/utils/cache/catcache.c
vendored
20
src/backend/utils/cache/catcache.c
vendored
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/cache/catcache.c,v 1.126 2005/11/22 18:17:24 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/cache/catcache.c,v 1.127 2006/01/07 21:16:10 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -356,7 +356,16 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
|
|||||||
Assert(ct->my_cache == cache);
|
Assert(ct->my_cache == cache);
|
||||||
|
|
||||||
if (ct->c_list)
|
if (ct->c_list)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* The cleanest way to handle this is to call CatCacheRemoveCList,
|
||||||
|
* which will recurse back to me, and the recursive call will do the
|
||||||
|
* work. Set the "dead" flag to make sure it does recurse.
|
||||||
|
*/
|
||||||
|
ct->dead = true;
|
||||||
CatCacheRemoveCList(cache, ct->c_list);
|
CatCacheRemoveCList(cache, ct->c_list);
|
||||||
|
return; /* nothing left to do */
|
||||||
|
}
|
||||||
|
|
||||||
/* delink from linked lists */
|
/* delink from linked lists */
|
||||||
DLRemove(&ct->lrulist_elem);
|
DLRemove(&ct->lrulist_elem);
|
||||||
@ -375,6 +384,8 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
|
|||||||
* CatCacheRemoveCList
|
* CatCacheRemoveCList
|
||||||
*
|
*
|
||||||
* Unlink and delete the given cache list entry
|
* Unlink and delete the given cache list entry
|
||||||
|
*
|
||||||
|
* NB: any dead member entries that become unreferenced are deleted too.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
CatCacheRemoveCList(CatCache *cache, CatCList *cl)
|
CatCacheRemoveCList(CatCache *cache, CatCList *cl)
|
||||||
@ -391,6 +402,13 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
|
|||||||
|
|
||||||
Assert(ct->c_list == cl);
|
Assert(ct->c_list == cl);
|
||||||
ct->c_list = NULL;
|
ct->c_list = NULL;
|
||||||
|
/* if the member is dead and now has no references, remove it */
|
||||||
|
if (
|
||||||
|
#ifndef CATCACHE_FORCE_RELEASE
|
||||||
|
ct->dead &&
|
||||||
|
#endif
|
||||||
|
ct->refcount == 0)
|
||||||
|
CatCacheRemoveCTup(cache, ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* delink from linked list */
|
/* delink from linked list */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user