Memory leakage associated with plperl spi_prepare/spi_freeplan

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: pgsql-hackers(at)postgreSQL(dot)org
Cc: Christian Schrder <cs(at)deriva(dot)de>
Subject: Memory leakage associated with plperl spi_prepare/spi_freeplan
Date: 2013-02-26 22:56:59
Message-ID: 28528.1361919419@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

I looked into the problem described here:
http://www.postgresql.org/message-id/5125087D.8090105@deriva.de

The core of the problem is that plperl's plperl_spi_prepare() sets up
input conversion functions for the parameters of a prepared query
using perm_fmgr_info(), which allocates FmgrInfo structs for the
I/O functions in TopMemoryContext and makes their fn_mcxt values point
to TopMemoryContext too. So when domains.c allocates assorted stuff
in fn_mcxt, that stuff lives forever ... but guess what, the prepared
query doesn't. So we have a memory leak on every use of spi_freeplan().

The leak is particularly egregious for this specific test case, where
an 8K-or-so ExprContext is made as a consequence of domain_check_input's
call to CreateStandaloneExprContext(); but it would add up to something
noticeable eventually even with input functions as innocuous as int4in.
Proof is to try this:

create or replace function perlleak(n int) returns void as $$
my ($n) = @_;
while ($n--) {
my $stmt = spi_prepare('select $1', 'int');
spi_freeplan($stmt);
}
$$ language plperl volatile strict;

with repeat count of a million or so.

I'm surprised we've not seen this reported before --- maybe people
don't tend to use spi_freeplan() much in plperl.

I'm inclined to think the right fix is to make a small memory context
for each prepared plan made by plperl_spi_prepare(). The qdesc for it
could be made right in the context (getting rid of the unchecked
malloc's near the top of the function), the FmgrInfos and their
subsidiary data could live there too, and plperl_spi_freeplan could
replace its retail free's with a single MemoryContextDelete.

Not being particularly a plperl user, I don't really want to code and
test this. Any takers?

regards, tom lane

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Tom Lane 2013-02-26 23:01:49 Re: initdb ignoring options?
Previous Message David E. Wheeler 2013-02-26 22:56:20 DBD::Pg PPM?