Re: Transaction-lifespan memory leak with plpgsql DO blocks

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Robert Haas <robertmhaas(at)gmail(dot)com>
Cc: "pgsql-hackers(at)postgresql(dot)org" <pgsql-hackers(at)postgresql(dot)org>, Yeb Havinga <yebhavinga(at)gmail(dot)com>
Subject: Re: Transaction-lifespan memory leak with plpgsql DO blocks
Date: 2013-11-14 21:23:52
Message-ID: 23061.1384464232@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

I wrote:
> Robert Haas <robertmhaas(at)gmail(dot)com> writes:
>> I'm not volunteering to spend time fixing this, but I disagree with
>> the premise that it isn't worth fixing, because I think it's a POLA
>> violation.

> Yeah, I'm not terribly comfortable with letting it go either. Attached
> is a proposed patch. I couldn't see any nice way to do it without adding
> a field to PLpgSQL_execstate, so this isn't a feasible solution for
> back-patching (it'd break the plpgsql debugger). However, given the
> infrequency of complaints, I think fixing it in 9.4 and up is good enough.

This patch crashed and burned when I tried it on a case where a DO block
traps an exception :-(. I had thought that a private econtext stack was
the right thing to do, but it isn't because we need plpgsql_subxact_cb
to be able to clean up dead econtexts in either functions or DO blocks.
So after some experimentation I came up with version 2, attached.
The additional test case I was using looks like

do $outer$
begin
for i in 1..100000 loop
begin
execute $e$
do $$
declare x int = 0;
begin
x := 1 / x;
end;
$$;
$e$;
exception when division_by_zero then null;
end;
end loop;
end;
$outer$;

If you try this with the patch, you'll notice that there's still a slow
leak, but that's not the fault of DO blocks: the same leak exists if you
transpose this code into a regular function. That leak is the fault of
exec_stmt_dynexecute, which copies the querystring into the function's
main execution context, from which it won't get freed if an error is
thrown out of SPI_execute. (If we were using EXECUTE USING, the "ppd"
structure would get leaked too.) There are some other similar error-
case leaks in other plpgsql statements, I think. I'm not excited
about trying to clean those up as part of this patch.

regards, tom lane

Attachment Content-Type Size
do-block-memory-leak-fix-2.patch text/x-diff 14.2 KB

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Pavel Stehule 2013-11-14 21:30:06 Re: Assertions in PL/PgSQL
Previous Message Piotr Marcinczyk 2013-11-14 21:11:56 Re: Add \i option to bring in the specified file as a quoted literal