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

Commit 8f55b9a

Browse files
committed
Avoid memory leakage when a series of subtransactions invoke AFTER triggers
that are fired at end-of-statement (as is the normal case for foreign keys, for example). In this situation the per-subxact deferred trigger context is always empty when subtransaction exit is reached; so we could free it, but were not doing so, leading to an intratransaction leak of 8K or more per subtransaction. Per off-list example from Viatcheslav Kalinin subsequent to bug #3418 (his original bug report omitted a foreign key constraint needed to cause this leak). Back-patch to 8.2; prior versions were not using per-subxact contexts for deferred triggers, so did not have this leak.
1 parent beba737 commit 8f55b9a

File tree

1 file changed

+19
-1
lines changed

1 file changed

+19
-1
lines changed

src/backend/commands/trigger.c

+19-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
99
* IDENTIFICATION
10-
* $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.214 2007/03/19 23:38:29 wieck Exp $
10+
* $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.215 2007/07/01 17:45:42 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -2814,6 +2814,24 @@ AfterTriggerEndSubXact(bool isCommit)
28142814
afterTriggers->state_stack[my_level] = NULL;
28152815
Assert(afterTriggers->query_depth ==
28162816
afterTriggers->depth_stack[my_level]);
2817+
/*
2818+
* It's entirely possible that the subxact created an event_cxt but
2819+
* there is not anything left in it (because all the triggers were
2820+
* fired at end-of-statement). If so, we should release the context
2821+
* to prevent memory leakage in a long sequence of subtransactions.
2822+
* We can detect whether there's anything of use in the context by
2823+
* seeing if anything was added to the global events list since
2824+
* subxact start. (This test doesn't catch every case where the
2825+
* context is deletable; for instance maybe the only additions were
2826+
* from a sub-sub-xact. But it handles the common case.)
2827+
*/
2828+
if (afterTriggers->cxt_stack[my_level] &&
2829+
afterTriggers->events.tail == afterTriggers->events_stack[my_level].tail)
2830+
{
2831+
MemoryContextDelete(afterTriggers->cxt_stack[my_level]);
2832+
/* avoid double delete if abort later */
2833+
afterTriggers->cxt_stack[my_level] = NULL;
2834+
}
28172835
}
28182836
else
28192837
{

0 commit comments

Comments
 (0)