From: | Jan Urbański <wulczer(at)wulczer(dot)org> |
---|---|
To: | Postgres - Hackers <pgsql-hackers(at)postgresql(dot)org> |
Subject: | plpgsql leaking memory when stringifying datums |
Date: | 2012-02-05 19:07:22 |
Message-ID: | 4F2ED36A.9020907@wulczer.org |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
While chasing a PL/Python memory leak, I did a few tests with PL/pgSQL
and I think there are places where memory is not freed sufficiently early.
Attached are two functions that when run will make the backend's memory
consumption increase until they finish. With both, the cause is
convert_value_to_string that calls a datum's output function, which for
toasted data results in an allocation.
The proposed patch changes convert_value_to_string to call the output
function in the per-tuple memory context and then copy the result string
back to the original context.
The comment in that function says that callers generally pfree its
result, but that wasn't the case with exec_stmt_raise, so I added a
pfree() there as well.
With that I was still left with a leak in the typecast() test function
and it turns out that sticking a exec_eval_cleanup into exec_move_row
fixed it. The regression tests pass, but I'm not 100% sure if it's
actually safe.
Since convert_value_to_string needed to access the PL/pgSQL's execution
state to get its hands on the per-tuple context, I needed to pass it to
every caller that didn't have it already, which means exec_cast_value
and exec_simple_cast_value. Anyone has a better idea?
The initial diagnosis and proposed solution are by Andres Freund - thanks!
Cheers,
Jan
Attachment | Content-Type | Size |
---|---|---|
plpgsql-convert-value-leak.patch | text/x-diff | 13.7 KB |
plpgsql-leaks.sql | application/x-sql | 529 bytes |
From | Date | Subject | |
---|---|---|---|
Next Message | Tom Lane | 2012-02-05 19:18:42 | Report: race conditions in WAL replay routines |
Previous Message | Jan Urbański | 2012-02-05 18:54:11 | pl/python long-lived allocations in datum->dict transformation |