Re: GetRelationPath() vs critical sections

From: Noah Misch <noah(at)leadboat(dot)com>
To: Andres Freund <andres(at)anarazel(dot)de>
Cc: pgsql-hackers(at)postgresql(dot)org
Subject: Re: GetRelationPath() vs critical sections
Date: 2024-09-04 19:03:53
Message-ID: 20240904190353.7b.nmisch@google.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Wed, Sep 04, 2024 at 11:58:33AM -0400, Andres Freund wrote:
> In general emitting a LOG inside a critical section isn't a huge issue - we
> made sure that elog.c has a reserve of memory to be able to log without
> crashing.
>
> However, the current message for buffer IO issues use relpath*() (ending up in
> a call to GetRelationPath()). Which in turn uses psprintf() to generate the
> path. Which in turn violates the no-memory-allocations-in-critical-sections
> rule, as the containing memory context will typically not have
> ->allowInCritSection == true.
>
> It's not obvious to me what the best way to deal with this is.
>
> One idea I had was to add an errrelpath() that switches to
> edata->assoc_context before calling relpath(), but that would end up leaking
> memory, as FreeErrorDataContents() wouldn't know about the allocation.
>
> Obviously we could add a version of GetRelationPath() that just prints into a
> caller provided buffer - but that's somewhat awkward API wise.

Agreed.

> A third approach would be to have a dedicated memory context for this kind of
> thing that's reset after logging the message - but that comes awkwardly close
> to duplicating ErrorContext.

That's how I'd try to do it. Today's ErrorContext is the context for
allocations FreeErrorDataContents() knows how to find. The new context would
be for calling into arbitrary code unknown to FreeErrorDataContents(). Most
of the time, we'd avoid reset work for the new context, since it would have no
allocations.

Ideally, errstart() would switch to the new context before returning true, and
errfinish() would switch back. That way, you could just call relpath*()
without an errrelpath() to help. This does need functions called in ereport()
argument lists to not use CurrentMemoryContext for allocations that need to
survive longer. I'd not be concerned about imposing that in a major release.
What obstacles would arise if we did that?

> I wonder if we're lacking a bit of infrastructure here...

Conceptually, the ereport() argument list should be a closure that runs in a
suitable mcxt. I think we're not far from the goal.

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Tom Lane 2024-09-04 19:08:13 Re: Large expressions in indexes can't be stored (non-TOASTable)
Previous Message Noah Misch 2024-09-04 18:43:22 Re: Use read streams in pg_visibility