Excerpts from Noah Misch's message of mar dic 13 11:44:49 -0300 2011:
>
> On Mon, Dec 12, 2011 at 05:20:39PM -0300, Alvaro Herrera wrote:
> > Excerpts from Noah Misch's message of dom dic 04 09:20:27 -0300 2011:
> >
> > > Second, I tried a SELECT FOR SHARE on a table of 1M tuples; this might incur
> > > some cost due to the now-guaranteed use of pg_multixact for FOR SHARE. See
> > > attached fklock-test-forshare.sql. The median run slowed by 7% under the
> > > patch, albeit with a rather brief benchmark run. Both master and patched
> > > PostgreSQL seemed to exhibit a statement-scope memory leak in this test case:
> > > to lock 1M rows, backend-private memory grew by about 500M. When trying 10M
> > > rows, I cancelled the query after 1.2 GiB of consumption. This limited the
> > > duration of a convenient test run.
> >
> > I found that this is caused by mxid_to_string being leaked all over the
> > place :-( I "fixed" it by making the returned string be a static that's
> > malloced and then freed on the next call. There's still virtsize growth
> > (not sure it's a legitimate leak) with that, but it's much smaller.
>
> Great. I'll retry that benchmark with the next patch version. I no longer
> see a leak on master, so I probably messed up that part of the test somehow.
Maybe you recompiled without the MULTIXACT_DEBUG symbol defined?
> By the way, do you have a rapid procedure for finding the call site behind a
> leak like this?
Not really ... I tried some games with GDB (which yielded the first
report: I did some "call MemoryContextStats(TopMemoryContext)" to see
where the bloat was, and then stepped with breaks on MemoryContextAlloc,
also with a watch on CurrentMemoryContext and noting when it was
pointing to the bloated context. But since I'm a rookie with GDB I
didn't find a way to only break when MemoryContextAlloc was pointing at
that context. I know there must be a way.) and then went to do some
code inspection instead. I gather some people use valgrind
successfully.
> > + if (str != NULL)
> > + free(str);
> > +
> > + str = malloc(15 * (nmembers + 1) + 4);
>
> Need a check for NULL return.
Yeah, thanks ... I changed it to MemoryContextAlloc(TopMemoryContext),
because I'm not sure that a combination of malloc plus palloc would end
up in extra memory fragmentation.
--
Álvaro Herrera <alvherre@commandprompt.com>
The PostgreSQL Company - Command Prompt, Inc.
PostgreSQL Replication, Consulting, Custom Development, 24x7 support