Re: Fix crash when non-creator being an iteration on shared radix tree

From: John Naylor <johncnaylorls(at)gmail(dot)com>
To: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
Cc: PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: Fix crash when non-creator being an iteration on shared radix tree
Date: 2024-12-19 06:32:46
Message-ID: CANWCAZZDCo4k5oURg_pPxM6+WZ1oiG=sqgjmQiELuyP0Vtrwig@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Thu, Dec 19, 2024 at 1:00 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
>
> On Tue, Dec 17, 2024 at 11:12 PM John Naylor <johncnaylorls(at)gmail(dot)com> wrote:
> > +1 in general, but I wonder if instead the iter_context should be
> > created within RT_BEGIN_ITERATE -- I imagine that would have less
> > duplication and would be as safe, but I haven't tried it. Is there
> > some reason not to do that?
>
> I agree that it has less duplication. There is no strong reason I
> didn't do that. I just didn't want to check 'if (!tree->iter_context)'
> in RT_BEGIN_ITERATE for simplicity. I've changed the patch
> accordingly.

I see what you mean. For v17, a bit of duplication is probably worth
it for simplicity, so I'd say v1 is fine there.

However, I think on master we should reconsider some aspects of memory
management more broadly:

1. The creator allocates the root of the tree in a new child context,
but an attaching process allocates it in its current context, and we
pfree it when the caller wants to detach. It seems like we could
always allocate this small struct in CurrentMemoryContext for
consistency.

2. The iter_context is separate because the creator's new context
could be a bump context which doesn't support pfree. But above we
assume we can pfree in the caller's context. Also, IIUC we only
allocate small iter objects, and it'd be unusual to need more than one
at a time per backend, so it's a bit strange to have an entire context
for that. Since we use a standard pattern of "begin; while(iter);
end;", it seems unlikely that someone will cause a leak because of a
coding mistake in iteration.

If these tiny admin structs were always, not sometimes, in the callers
current context, I think it would be easier to reason about because
then the creator's passed context would be used only for local memory,
specifically only for leaves and the inner node child contexts.
Thoughts?

Further,

3. I was never a fan of trying to second-guess the creator's new
context and instead use slab for fixed-sized leaf allocations. If the
creator passes a bump context, we say "no, no, no, use slab -- it's
good for ya". Let's assume the caller knows what they're doing.

4. For local memory, an allocated "control object" serves no real
purpose and wastes a few cycles on every access. I'm not sure it
matters that much as a future micro-optimization, but I mention it
here because if we did start allocating outer structs in the callers
context, embedding would also remove the need to pfree it.

--
John Naylor
Amazon Web Services

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message David Rowley 2024-12-19 06:33:20 Re: Converting SetOp to read its two inputs separately
Previous Message jian he 2024-12-19 06:28:21 in BeginCopyTo make materialized view using COPY TO instead of COPY (query).