Re: Memory leak in WAL sender with pgoutput (v10~)

Amit Kapila <amit.kapila16@gmail.com>

From: Amit Kapila <amit.kapila16@gmail.com>
To: Masahiko Sawada <sawada.mshk@gmail.com>
Cc: "Zhijie Hou (Fujitsu)" <houzj.fnst@fujitsu.com>, vignesh C <vignesh21@gmail.com>, Michael Paquier <michael@paquier.xyz>, Euler Taveira <euler@eulerto.com>, Alvaro Herrera <alvherre@alvh.no-ip.org>, Postgres hackers <pgsql-hackers@lists.postgresql.org>
Date: 2024-12-12T05:43:39Z
Lists: pgsql-hackers
On Wed, Dec 11, 2024 at 11:09 AM Masahiko Sawada <sawada.mshk@gmail.com> wrote:
>
> On Tue, Dec 10, 2024 at 6:13 PM Zhijie Hou (Fujitsu)
> <houzj.fnst@fujitsu.com> wrote:
> >
> > On Wednesday, December 11, 2024 2:14 AM Masahiko Sawada <sawada.mshk@gmail.com> wrote:
> > >
> > > On Tue, Dec 10, 2024 at 1:16 AM Amit Kapila <amit.kapila16@gmail.com>
> > > wrote:
> > > >
> > > > On Tue, Dec 10, 2024 at 11:24 AM Amit Kapila <amit.kapila16@gmail.com>
> > > wrote:
> > > > >
> > > > > On Tue, Dec 10, 2024 at 8:54 AM vignesh C <vignesh21@gmail.com>
> > > wrote:
> > > > > >
> > > > > > On Tue, 10 Dec 2024 at 04:56, Michael Paquier <michael@paquier.xyz>
> > > wrote:
> > > > > > >
> > > > > > > On Mon, Dec 09, 2024 at 03:36:15PM +0530, Amit Kapila wrote:
> > > > > > > > It couldn't solve the problem completely even in back-branches. The
> > > > > > > > SQL API case I mentioned and tested by Hou-San in the email [1]
> > > won't
> > > > > > > > be solved.
> > > > > > > >
> > > > > > > > [1] -
> > > https://www.postgresql.org/message-id/OS0PR01MB57166A4DA0ABBB94F
> > > 2FBB28694362%40OS0PR01MB5716.jpnprd01.prod.outlook.com
> > > > > > >
> > > > > > > Yeah, exactly (wanted to reply exactly that yesterday but lacked time,
> > > > > > > thanks!).
> > > > > >
> > > > > > Yes, that makes sense. How about something like the attached patch.
> > > > > >
> > > > >
> > > > > - oldctx = MemoryContextSwitchTo(CacheMemoryContext);
> > > > > - if (data->publications)
> > > > > - {
> > > > > - list_free_deep(data->publications);
> > > > > - data->publications = NIL;
> > > > > - }
> > > > > + static MemoryContext pubctx = NULL;
> > > > > +
> > > > > + if (pubctx == NULL)
> > > > > + pubctx = AllocSetContextCreate(CacheMemoryContext,
> > > > > +    "logical replication publication list context",
> > > > > +    ALLOCSET_SMALL_SIZES);
> > > > > + else
> > > > > + MemoryContextReset(pubctx);
> > > > > +
> > > > > + oldctx = MemoryContextSwitchTo(pubctx);
> > > > >
> > > > > Considering the SQL API case, why is it okay to allocate this context
> > > > > under CacheMemoryContext?
> > > > >
> > > >
> > > > On further thinking, we can't allocate it under
> > > > LogicalDecodingContext->context because once that is freed at the end
> > > > of SQL API pg_logical_slot_get_changes(), pubctx will be pointing to a
> > > > dangling memory. One idea is that we use
> > > > MemoryContextRegisterResetCallback() to invoke a reset callback
> > > > function where we can reset pubctx but not sure if we want to go there
> > > > in back branches. OTOH, the currently proposed fix won't leak memory
> > > > on repeated calls to pg_logical_slot_get_changes(), so that might be
> > > > okay as well.
> > > >
> > > > Thoughts?
> > >
> > > Alternative idea is to declare pubctx as a file static variable. And
> > > we create the memory context under LogicalDecodingContext->context in
> > > the startup callback and free it in the shutdown callback.
> >
> > I think when an ERROR occurs during the execution of the pg_logical_slot_xx()
> > API, the shutdown callback function is not invoked. This would result in the
> > static variable not being reset, which, I think, is why Amit mentioned the use
> > of MemoryContextRegisterResetCallback().
>
> My idea is that since that new context is cleaned up together with its
> parent context (LogicalDecodingContext->context), we unconditionally
> set that new context to the static variable at the startup callback.
> That being said, Amit's idea would be cleaner.
>

Your preference is not completely clear. Are you okay with the idea of
Vignesh's currently proposed patch for back-branches, or do you prefer
to use a memory context reset callback, or do you have a different
idea that should be adopted for back-branches?

-- 
With Regards,
Amit Kapila.



Commits

  1. Fix memory leak in pgoutput with relation attribute map

  2. Fix memory leak in pgoutput with publication list cache

  3. Allow specifying row filters for logical replication of tables.