Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit b64826a

Browse files
committed
Squash longstanding memory leak: when catcache.c copied a tuple into
the cache context, it didn't bother to free the tuple that CatalogIndexFetchTuple had allocated in the transaction context. Do enough cache lookups in the same xact, and you start to notice...
1 parent 16d0adb commit b64826a

File tree

1 file changed

+24
-12
lines changed

1 file changed

+24
-12
lines changed

src/backend/utils/cache/catcache.c

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.59 2000/01/31 04:35:51 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.60 2000/02/04 03:16:03 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -905,7 +905,7 @@ SearchSysCache(struct catcache * cache,
905905
CatCTup *nct;
906906
CatCTup *nct2;
907907
Dlelem *elt;
908-
HeapTuple ntp = 0;
908+
HeapTuple ntp = NULL;
909909

910910
Relation relation;
911911
MemoryContext oldcxt;
@@ -1039,32 +1039,42 @@ SearchSysCache(struct catcache * cache,
10391039
* wieck - 10/18/1996
10401040
* ----------
10411041
*/
1042+
HeapTuple indextp;
1043+
10421044
MemoryContextSwitchTo(oldcxt);
10431045
Assert(cache->cc_iscanfunc);
10441046
switch (cache->cc_nkeys)
10451047
{
10461048
case 4:
1047-
ntp = cache->cc_iscanfunc(relation, v1, v2, v3, v4);
1049+
indextp = cache->cc_iscanfunc(relation, v1, v2, v3, v4);
10481050
break;
10491051
case 3:
1050-
ntp = cache->cc_iscanfunc(relation, v1, v2, v3);
1052+
indextp = cache->cc_iscanfunc(relation, v1, v2, v3);
10511053
break;
10521054
case 2:
1053-
ntp = cache->cc_iscanfunc(relation, v1, v2);
1055+
indextp = cache->cc_iscanfunc(relation, v1, v2);
10541056
break;
10551057
case 1:
1056-
ntp = cache->cc_iscanfunc(relation, v1);
1058+
indextp = cache->cc_iscanfunc(relation, v1);
1059+
break;
1060+
default:
1061+
indextp = NULL;
10571062
break;
10581063
}
10591064
/* ----------
10601065
* Back to Cache context. If we got a tuple copy it
1061-
* into our context.
1062-
* wieck - 10/18/1996
1066+
* into our context. wieck - 10/18/1996
1067+
* And free the tuple that was allocated in the
1068+
* transaction's context. tgl - 02/03/2000
10631069
* ----------
10641070
*/
1071+
if (HeapTupleIsValid(indextp)) {
1072+
MemoryContextSwitchTo((MemoryContext) CacheCxt);
1073+
ntp = heap_copytuple(indextp);
1074+
MemoryContextSwitchTo(oldcxt);
1075+
heap_freetuple(indextp);
1076+
}
10651077
MemoryContextSwitchTo((MemoryContext) CacheCxt);
1066-
if (HeapTupleIsValid(ntp))
1067-
ntp = heap_copytuple(ntp);
10681078
}
10691079
else
10701080
{
@@ -1089,6 +1099,7 @@ SearchSysCache(struct catcache * cache,
10891099
{
10901100
CACHE1_elog(DEBUG, "SearchSysCache: found tuple");
10911101
ntp = heap_copytuple(ntp);
1102+
/* We should not free the result of heap_getnext... */
10921103
}
10931104

10941105
MemoryContextSwitchTo(oldcxt);
@@ -1101,8 +1112,8 @@ SearchSysCache(struct catcache * cache,
11011112
cache->busy = false;
11021113

11031114
/* ----------------
1104-
* scan is complete. if tup is valid, we copy it and add the copy to
1105-
* the cache.
1115+
* scan is complete. if tup is valid, we can add it to the cache.
1116+
* note we have already copied it into the cache memory context.
11061117
* ----------------
11071118
*/
11081119
if (HeapTupleIsValid(ntp))
@@ -1168,6 +1179,7 @@ SearchSysCache(struct catcache * cache,
11681179
heap_close(relation, AccessShareLock);
11691180

11701181
MemoryContextSwitchTo(oldcxt);
1182+
11711183
return ntp;
11721184
}
11731185

0 commit comments

Comments
 (0)