Thread: BUG #4677: memory growth

BUG #4677: memory growth

From
"aiwaniuk"
Date:
The following bug has been logged online:

Bug reference:      4677
Logged by:          aiwaniuk
Email address:      aiwaniuk@instytut.com.pl
PostgreSQL version: >8.0
Operating system:   linux
Description:        memory growth
Details:

i postgres version 8.2, 8.3 and probobly 8.1 there is problem with running
VOLATILE  plpgsql function with begin - exception checking that performs
other VOLATILE  plpgsql function. if either, first or second performing
removed, problem doesn't shows. here's an example

CREATE FUNCTION info.f()
  RETURNS void AS
$BODY$
DECLARE
  tmp text;
BEGIN
  -- do anything
  tmp = md5(random()::text) || md5(random()::text);
  RETURN;
END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE;

CREATE or replace FUNCTION info.memory_growth(i_max integer)
  RETURNS integer AS
$BODY$
DECLARE
  i integer;
BEGIN
  i = 0;
  WHILE  i < i_max  LOOP

    BEGIN
      PERFORM info.f();
    EXCEPTION
      WHEN OTHERS THEN
        --
    END;

    PERFORM info.f();

    i = i + 1;
  END LOOP;

  RETURN i;
END;$BODY$
  LANGUAGE 'plpgsql' VOLATILE;

after running
select info.memory_growth(100000);

please take a look how's memory of client process grows. is there some
logical problem how functions are create ?

Re: BUG #4677: memory growth

From
Tom Lane
Date:
"aiwaniuk" <aiwaniuk@instytut.com.pl> writes:
> i postgres version 8.2, 8.3 and probobly 8.1 there is problem with running
> VOLATILE  plpgsql function with begin - exception checking that performs
> other VOLATILE  plpgsql function. if either, first or second performing
> removed, problem doesn't shows. here's an example

The reason there's an issue here is that you're invoking the same
function f() both inside and outside the subtransactions caused by
the begin/exception block.  The expressions inside f() get re-prepared
each time the subtransaction ID changes.  The memory this eats is
reclaimed at subtransaction end.  So the memory used by the call inside
the begin/exception block is cleaned up immediately, but the memory
used by the other call accumulates in the outer subtransaction's
workspace.

We'll think about how to fix this, but you shouldn't expect that a
fix will appear quickly.  A possible workaround is to put another
begin/exception block around the other call of the function.

            regards, tom lane

Re: BUG #4677: memory growth

From
aiwaniuk@instytut.com.pl
Date:
On Thu, Feb 26, 2009 at 03:50:16PM -0500, Tom Lane wrote:
> "aiwaniuk" <aiwaniuk@instytut.com.pl> writes:
> > i postgres version 8.2, 8.3 and probobly 8.1 there is problem with running
> The reason there's an issue here is that you're invoking the same
> function f() both inside and outside the subtransactions caused by
> the begin/exception block.  The expressions inside f() get re-prepared
> each time the subtransaction ID changes.  The memory this eats is
> reclaimed at subtransaction end.  So the memory used by the call inside
> the begin/exception block is cleaned up immediately, but the memory
> used by the other call accumulates in the outer subtransaction's
> workspace.

thanks for replay.

i have to say something more. i see that if there is one perform
of f() (no matter if it is begin - exception block, or not) postgres
process consumes 450MB of memory. but if there are two executions of
f(), and i make
select info.memory_growth(1000000);
postgres process consumes 5.2GB of memory. this is way too much...
or not ? isn't it some bug in memory reciment ?

executing f() only once, consumes as i mention, 450MB of
memory. changing number of loops in execution do not lead to memory
growth. if we performing two executions of f() (one in begin -
exception block) used memory is growing, on and on. i have 13GB of
memory, and multiplying number loops by 10 (from 1000000 to 10000000)
causes server crash - not enough memory.

there is  one interesting thing, if i create a copy of f() function (lets say
f1), and function f() is performing in begin-exception block, and f1()
is performing in main block, mamory do not grows!! postgres constantly
uses 450MB interesting, isn't it ?

looking forward for comment

Re: BUG #4677: memory growth

From
aiwaniuk@instytut.com.pl
Date:
On Thu, Feb 26, 2009 at 03:50:16PM -0500, Tom Lane wrote:
> The reason there's an issue here is that you're invoking the same

i'v forgotten to mention that this behavior we saw when we
had migrated one database from version 8.0 to 8.3. further test showed, that
in v8.2 this problem is also seen. versions 8.0 and 8.1 (at least 8.1.3)  are
insensitive to this issue.