Re: add function for creating/attaching hash table in DSM registry

From: Nathan Bossart <nathandbossart(at)gmail(dot)com>
To: Sami Imseih <samimseih(at)gmail(dot)com>
Cc: Florents Tselai <florents(dot)tselai(at)gmail(dot)com>, Dagfinn Ilmari Mannsåker <ilmari(at)ilmari(dot)org>, pgsql-hackers(at)postgresql(dot)org
Subject: Re: add function for creating/attaching hash table in DSM registry
Date: 2025-06-10 20:21:34
Message-ID: aEiTzmndOVPmA6Mm@nathan
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Tue, Jun 10, 2025 at 02:05:16PM -0500, Sami Imseih wrote:
> There is also that dynamic tranche named are stored in local backend
> look-up table, so if you have some backends that attached some dynamic
> hash table
> and others that did not, only the ones that registered would be able to
> resolve the tranche id to its name.
>
> This is the case which I encountered yesterday, in which I tested 2
> backends competing for a LWLock on the dshash table, but a third backend
> that did not attach the hashtable reported the wait_event as "extension"
> rather than the extension-specified tranche name.
>
> If that third backend attaches the hash table, then it's able to report
> the wait_event as the tranche name specified by the extension. So that
> could be confusing as 2 wait events could be reported for the same
> code path. right?

My initial reaction to this was "well yeah, that's how it's designed." But
after some more research, I see that LWLockRegisterTranche() (commit
ea9df81) predates both the removal of dynamic_shared_memory_type=none
(commit bcbd940) and the introduction of DSAs (commit 13df76a). lwlock.h
even still has this (arguably outdated) comment:

* It may seem strange that each process using the tranche must register it
* separately, but dynamic shared memory segments aren't guaranteed to be
* mapped at the same address in all coordinating backends, so storing the
* registration in the main shared memory segment wouldn't work for that case.

So, if we were adding named LWLocks today, I suspect we might do it
differently. The first thing that comes to mind is that we could store a
shared LWLockTrancheNames table and stop requiring each backend to register
them individually. For a concrete example, the autoprewarm shared memory
initialization code would become something like:

static void
apw_init_state(void *ptr)
{
AutoPrewarmSharedState *state = (AutoPrewarmSharedState *) ptr;

LWLockInitialize(&state->lock, LWLockNewTrancheId("autoprewarm"));
...
}

static bool
apw_init_shmem(void)
{
bool found;

apw_state = GetNamedDSMSegment("autoprewarm",
sizeof(AutoPrewarmSharedState),
apw_init_state,
&found);
return found;
}

In short, LWLockNewTrancheId() would gain a new name argument, and
LWLockRegisterTranche() would disappear. We would probably need to be
smart to avoid contention on the name table, but that feels avoidable to
me.

--
nathan

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Nathan Bossart 2025-06-10 20:33:01 Re: Improve tab completion for COPY
Previous Message Alexander Korotkov 2025-06-10 20:14:16 Re: Slot's restart_lsn may point to removed WAL segment after hard restart unexpectedly