Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit257cccb

Browse files
committed
Add some marginal tweaks to eliminate memory leakages associated with
subtransactions. Trivial subxacts (such as a plpgsql exception blockcontaining no database access) now demonstrably leak zero bytes.
1 parent86fff99 commit257cccb

File tree

6 files changed

+118
-16
lines changed

6 files changed

+118
-16
lines changed

‎src/backend/access/transam/xact.c

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
*
1212
* IDENTIFICATION
13-
* $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.189 2004/09/1616:58:26 tgl Exp $
13+
* $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.190 2004/09/1620:17:16 tgl Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -861,9 +861,6 @@ AtCommit_Memory(void)
861861

862862
/*
863863
* AtSubCommit_Memory
864-
*
865-
* We do not throw away the child's CurTransactionContext, since the data
866-
* it contains will be needed at upper commit.
867864
*/
868865
staticvoid
869866
AtSubCommit_Memory(void)
@@ -875,6 +872,18 @@ AtSubCommit_Memory(void)
875872
/* Return to parent transaction level's memory context. */
876873
CurTransactionContext=s->parent->curTransactionContext;
877874
MemoryContextSwitchTo(CurTransactionContext);
875+
876+
/*
877+
* Ordinarily we cannot throw away the child's CurTransactionContext,
878+
* since the data it contains will be needed at upper commit. However,
879+
* if there isn't actually anything in it, we can throw it away. This
880+
* avoids a small memory leak in the common case of "trivial" subxacts.
881+
*/
882+
if (MemoryContextIsEmpty(s->curTransactionContext))
883+
{
884+
MemoryContextDelete(s->curTransactionContext);
885+
s->curTransactionContext=NULL;
886+
}
878887
}
879888

880889
/*
@@ -890,13 +899,27 @@ AtSubCommit_childXids(void)
890899

891900
Assert(s->parent!=NULL);
892901

893-
old_cxt=MemoryContextSwitchTo(s->parent->curTransactionContext);
902+
/*
903+
* We keep the child-XID lists in TopTransactionContext; this avoids
904+
* setting up child-transaction contexts for what might be just a few
905+
* bytes of grandchild XIDs.
906+
*/
907+
old_cxt=MemoryContextSwitchTo(TopTransactionContext);
894908

895909
s->parent->childXids=lappend_xid(s->parent->childXids,
896910
s->transactionId);
897911

898-
s->parent->childXids=list_concat(s->parent->childXids,s->childXids);
899-
s->childXids=NIL;/* ensure list not doubly referenced */
912+
if (s->childXids!=NIL)
913+
{
914+
s->parent->childXids=list_concat(s->parent->childXids,
915+
s->childXids);
916+
/*
917+
* list_concat doesn't free the list header for the second list;
918+
* do so here to avoid memory leakage (kluge)
919+
*/
920+
pfree(s->childXids);
921+
s->childXids=NIL;
922+
}
900923

901924
MemoryContextSwitchTo(old_cxt);
902925
}
@@ -1092,6 +1115,23 @@ AtSubAbort_Memory(void)
10921115
MemoryContextSwitchTo(TopTransactionContext);
10931116
}
10941117

1118+
/*
1119+
* AtSubAbort_childXids
1120+
*/
1121+
staticvoid
1122+
AtSubAbort_childXids(void)
1123+
{
1124+
TransactionStates=CurrentTransactionState;
1125+
1126+
/*
1127+
* We keep the child-XID lists in TopTransactionContext (see
1128+
* AtSubCommit_childXids). This means we'd better free the list
1129+
* explicitly at abort to avoid leakage.
1130+
*/
1131+
list_free(s->childXids);
1132+
s->childXids=NIL;
1133+
}
1134+
10951135
/*
10961136
* RecordSubTransactionAbort
10971137
*/
@@ -3317,7 +3357,10 @@ AbortSubTransaction(void)
33173357

33183358
/* Advertise the fact that we aborted in pg_clog. */
33193359
if (TransactionIdIsValid(s->transactionId))
3360+
{
33203361
RecordSubTransactionAbort();
3362+
AtSubAbort_childXids();
3363+
}
33213364

33223365
/* Post-abort cleanup */
33233366
CallSubXactCallbacks(SUBXACT_EVENT_ABORT_SUB,s->subTransactionId,

‎src/backend/executor/spi.c

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.128 2004/09/1616:58:29 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.129 2004/09/1620:17:20 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -104,6 +104,8 @@ SPI_connect(void)
104104
_SPI_current=&(_SPI_stack[_SPI_connected]);
105105
_SPI_current->processed=0;
106106
_SPI_current->tuptable=NULL;
107+
_SPI_current->procCxt=NULL;/* in case we fail to create 'em */
108+
_SPI_current->execCxt=NULL;
107109
_SPI_current->connectSubid=GetCurrentSubTransactionId();
108110

109111
/*
@@ -144,7 +146,9 @@ SPI_finish(void)
144146

145147
/* Release memory used in procedure call */
146148
MemoryContextDelete(_SPI_current->execCxt);
149+
_SPI_current->execCxt=NULL;
147150
MemoryContextDelete(_SPI_current->procCxt);
151+
_SPI_current->procCxt=NULL;
148152

149153
/*
150154
* Reset result variables, especially SPI_tuptable which is probably
@@ -214,11 +218,24 @@ AtEOSubXact_SPI(bool isCommit, SubTransactionId mySubid)
214218

215219
found= true;
216220

221+
/*
222+
* Release procedure memory explicitly (see note in SPI_connect)
223+
*/
224+
if (connection->execCxt)
225+
{
226+
MemoryContextDelete(connection->execCxt);
227+
connection->execCxt=NULL;
228+
}
229+
if (connection->procCxt)
230+
{
231+
MemoryContextDelete(connection->procCxt);
232+
connection->procCxt=NULL;
233+
}
234+
217235
/*
218236
* Pop the stack entry and reset global variables.Unlike
219237
* SPI_finish(), we don't risk switching to memory contexts that
220-
* might be already gone, or deleting memory contexts that have
221-
* been or will be thrown away anyway.
238+
* might be already gone.
222239
*/
223240
_SPI_connected--;
224241
_SPI_curid=_SPI_connected;

‎src/backend/utils/mmgr/aset.c

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
* Portions Copyright (c) 1994, Regents of the University of California
1212
*
1313
* IDENTIFICATION
14-
* $PostgreSQL: pgsql/src/backend/utils/mmgr/aset.c,v 1.57 2004/08/29 05:06:51 momjian Exp $
14+
* $PostgreSQL: pgsql/src/backend/utils/mmgr/aset.c,v 1.58 2004/09/16 20:17:33 tgl Exp $
1515
*
1616
* NOTE:
1717
*This is a new (Feb. 05, 1999) implementation of the allocation set
@@ -205,6 +205,7 @@ static void AllocSetInit(MemoryContext context);
205205
staticvoidAllocSetReset(MemoryContextcontext);
206206
staticvoidAllocSetDelete(MemoryContextcontext);
207207
staticSizeAllocSetGetChunkSpace(MemoryContextcontext,void*pointer);
208+
staticboolAllocSetIsEmpty(MemoryContextcontext);
208209
staticvoidAllocSetStats(MemoryContextcontext);
209210

210211
#ifdefMEMORY_CONTEXT_CHECKING
@@ -222,6 +223,7 @@ static MemoryContextMethods AllocSetMethods = {
222223
AllocSetReset,
223224
AllocSetDelete,
224225
AllocSetGetChunkSpace,
226+
AllocSetIsEmpty,
225227
AllocSetStats
226228
#ifdefMEMORY_CONTEXT_CHECKING
227229
,AllocSetCheck
@@ -991,6 +993,26 @@ AllocSetGetChunkSpace(MemoryContext context, void *pointer)
991993
returnchunk->size+ALLOC_CHUNKHDRSZ;
992994
}
993995

996+
/*
997+
* AllocSetIsEmpty
998+
*Is an allocset empty of any allocated space?
999+
*/
1000+
staticbool
1001+
AllocSetIsEmpty(MemoryContextcontext)
1002+
{
1003+
AllocSetset= (AllocSet)context;
1004+
1005+
/*
1006+
* For now, we say "empty" only if the context never contained any
1007+
* space at all. We could examine the freelists to determine if all
1008+
* space has been freed, but it's not really worth the trouble for
1009+
* present uses of this functionality.
1010+
*/
1011+
if (set->blocks==NULL)
1012+
return true;
1013+
return false;
1014+
}
1015+
9941016
/*
9951017
* AllocSetStats
9961018
*Displays stats about memory consumption of an allocset.

‎src/backend/utils/mmgr/mcxt.c

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
*
1515
*
1616
* IDENTIFICATION
17-
* $PostgreSQL: pgsql/src/backend/utils/mmgr/mcxt.c,v 1.50 2004/08/29 05:06:51 momjian Exp $
17+
* $PostgreSQL: pgsql/src/backend/utils/mmgr/mcxt.c,v 1.51 2004/09/16 20:17:33 tgl Exp $
1818
*
1919
*-------------------------------------------------------------------------
2020
*/
@@ -291,6 +291,25 @@ GetMemoryChunkContext(void *pointer)
291291
returnheader->context;
292292
}
293293

294+
/*
295+
* MemoryContextIsEmpty
296+
*Is a memory context empty of any allocated space?
297+
*/
298+
bool
299+
MemoryContextIsEmpty(MemoryContextcontext)
300+
{
301+
AssertArg(MemoryContextIsValid(context));
302+
303+
/*
304+
* For now, we consider a memory context nonempty if it has any children;
305+
* perhaps this should be changed later.
306+
*/
307+
if (context->firstchild!=NULL)
308+
return false;
309+
/* Otherwise use the type-specific inquiry */
310+
return (*context->methods->is_empty) (context);
311+
}
312+
294313
/*
295314
* MemoryContextStats
296315
*Print statistics about the named context and all its descendants.
@@ -662,7 +681,6 @@ void
662681
pgport_pfree(void*pointer)
663682
{
664683
pfree(pointer);
665-
return;
666684
}
667685

668-
#endif
686+
#endif/* WIN32 */

‎src/include/nodes/memnodes.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/nodes/memnodes.h,v 1.28 2004/08/29 04:13:07 momjian Exp $
10+
* $PostgreSQL: pgsql/src/include/nodes/memnodes.h,v 1.29 2004/09/16 20:17:42 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -43,6 +43,7 @@ typedef struct MemoryContextMethods
4343
void(*reset) (MemoryContextcontext);
4444
void(*delete) (MemoryContextcontext);
4545
Size(*get_chunk_space) (MemoryContextcontext,void*pointer);
46+
bool(*is_empty) (MemoryContextcontext);
4647
void(*stats) (MemoryContextcontext);
4748
#ifdefMEMORY_CONTEXT_CHECKING
4849
void(*check) (MemoryContextcontext);

‎src/include/utils/memutils.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
1111
* Portions Copyright (c) 1994, Regents of the University of California
1212
*
13-
* $PostgreSQL: pgsql/src/include/utils/memutils.h,v 1.57 2004/08/29 04:13:11 momjian Exp $
13+
* $PostgreSQL: pgsql/src/include/utils/memutils.h,v 1.58 2004/09/16 20:17:49 tgl Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -91,6 +91,7 @@ extern void MemoryContextDeleteChildren(MemoryContext context);
9191
externvoidMemoryContextResetAndDeleteChildren(MemoryContextcontext);
9292
externSizeGetMemoryChunkSpace(void*pointer);
9393
externMemoryContextGetMemoryChunkContext(void*pointer);
94+
externboolMemoryContextIsEmpty(MemoryContextcontext);
9495
externvoidMemoryContextStats(MemoryContextcontext);
9596

9697
#ifdefMEMORY_CONTEXT_CHECKING

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp