mirror of
https://github.com/postgres/postgres.git
synced 2025-05-03 22:24:49 +03:00
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.
This commit is contained in:
parent
f6eafabc6e
commit
b60765944d
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.210.2.1 2007/01/25 04:17:56 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.210.2.2 2007/07/01 17:45:49 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -2766,6 +2766,24 @@ AfterTriggerEndSubXact(bool isCommit)
|
|||||||
afterTriggers->state_stack[my_level] = NULL;
|
afterTriggers->state_stack[my_level] = NULL;
|
||||||
Assert(afterTriggers->query_depth ==
|
Assert(afterTriggers->query_depth ==
|
||||||
afterTriggers->depth_stack[my_level]);
|
afterTriggers->depth_stack[my_level]);
|
||||||
|
/*
|
||||||
|
* It's entirely possible that the subxact created an event_cxt but
|
||||||
|
* there is not anything left in it (because all the triggers were
|
||||||
|
* fired at end-of-statement). If so, we should release the context
|
||||||
|
* to prevent memory leakage in a long sequence of subtransactions.
|
||||||
|
* We can detect whether there's anything of use in the context by
|
||||||
|
* seeing if anything was added to the global events list since
|
||||||
|
* subxact start. (This test doesn't catch every case where the
|
||||||
|
* context is deletable; for instance maybe the only additions were
|
||||||
|
* from a sub-sub-xact. But it handles the common case.)
|
||||||
|
*/
|
||||||
|
if (afterTriggers->cxt_stack[my_level] &&
|
||||||
|
afterTriggers->events.tail == afterTriggers->events_stack[my_level].tail)
|
||||||
|
{
|
||||||
|
MemoryContextDelete(afterTriggers->cxt_stack[my_level]);
|
||||||
|
/* avoid double delete if abort later */
|
||||||
|
afterTriggers->cxt_stack[my_level] = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user