Re: Call CalculateShmemSize() only once

From: Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>
To: Nathan Bossart <nathandbossart(at)gmail(dot)com>
Cc: PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>, Heikki Linnakangas <heikki(dot)linnakangas(at)databricks(dot)com>
Subject: Re: Call CalculateShmemSize() only once
Date: 2026-11-02 10:11:41
Message-ID: CAExHW5uc4LodxiiY6S5uOaUNJk9wK-fXt93Ak-g4LJvLEzJ5jg@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Fri, Oct 30, 2026 at 11:25 PM Nathan Bossart
<nathandbossart(at)gmail(dot)com> wrote:
>
> > As a follow-up, would it make sense to introduce an SRS_SIZED state
> > between SRS_REQUESTING and SRS_INITIALIZING? We could enter it when
> > ShmemGetRequestedSize() finishes and adjust the state checks
> > accordingly. This would prevent new requests from being registered
> > after the required shared memory size has been calculated.
> > EXEC_BACKEND child attachment and late allocation would retain their
> > existing paths without entering this state. I can update the patch if
> > this seems worthwhile.
>
> Seems worth exploring.

Done. This is a small change that fits the existing state machine. I
have included it as a separate patch for review; it could be merged
into the CalculateShmemSize() patch with an updated commit message.

> > /*
> > * CalculateShmemSize
> > * Calculates the amount of shared memory needed.
> > + *
> > + * Expected to be called only once after collecting all shared memory requests
> > + * but before allocating the shared memory segment at the startup or server
> > + * restart.
> > */
>
> Should we ERROR if it is called more than once? That might need some
> special handling for the restart_after_crash case.
>

With this change, a second call to ShmemGetRequestedSize() during the
same shared-memory initialization cycle fails
Assert(shmem_request_state == SRS_REQUESTING) in assertion-enabled
builds. This also detects repeated calls through CalculateShmemSize().
I think an assertion is sufficient here because this is an internal
lifecycle invariant, consistent with the other state-transition
assertions. Attempts to register requests after sizing are still
rejected by the existing runtime checks.

For restart_after_crash, ResetShmemAllocator() resets the state to
SRS_INITIAL. The request callbacks then start a fresh request phase,
allowing the size to be calculated again for the new segment.

>
> > - CreateSharedMemoryAndSemaphores();
> > + shmem_size = CalculateShmemSize();
> > + CreateSharedMemoryAndSemaphores(shmem_size);
>
> nitpick: When the variable is only used in one place, is there any reason
> not to just do CreateSharedMemoryAndSemaphores(CalculateShmemSize())?
>

I find a separate variable more readable. Your suggestion looks ok
too. Changed as suggested in the bootstrap and crash-restart paths.
The normal postmaster and single-user startup paths retain the
variable because they also pass the size to InitializeShmemGUCs().

> > -CreateSharedMemoryAndSemaphores(void)
> > +CreateSharedMemoryAndSemaphores(Size size)
>
> Should we verify the size looks reasonable? A "!= 0" check might be
> worthwhile, at least.

Both the Unix and Windows implementations of PGSharedMemoryCreate(),
called by CreateSharedMemoryAndSemaphores(), already contain:
/* Room for a header? */
Assert(size > MAXALIGN(sizeof(PGShmemHeader)));

These assertions run before allocating the shared-memory segment and
enforce a stronger condition than size != 0. I have therefore left out
the additional check in CreateSharedMemoryAndSemaphores(). Happy to
add it if you would prefer an explicit assertion at that entry point
too.

>
> > - * ShmemGetRequestedSize() --- estimate the total size of all registered shared
> > - * memory structures.
> > + * ShmemGetRequestedSize() --- estimate the total size of all registered shared
> > + * memory structures.
>
> nitpick: Unnecessary changes.
>

+1. Fixed.

> > - * This is called at postmaster startup, before the shared memory segment has
> > - * been created.
> > + * This is called at postmaster startup or server restart, before the shared
> > + * memory segment has been created.
>
> nitpick: This also seems unnecessary, or at least unrelated to the patch at
> hand.
>

"or server restart" should have been mentioned explicitly here even
without this change, and now that we are tightening this contract
further, I thought it would be better to mention it. Reverted it now.

Please find attached the revised patches.

--
Best Wishes,
Ashutosh Bapat

Attachment Content-Type Size
v20261102-0002-Introduce-SRS_SIZED.patch text/x-patch 2.2 KB
v20261102-0001-Call-CalculateShmemSize-only-once-when-cre.patch text/x-patch 7.9 KB

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Jingtang Zhang 2026-11-02 10:13:33 Stale hash entries when reusing an auxiliary resource owner
Previous Message Jim Jones 2026-11-02 10:06:34 Re: Reject access to unlogged tables in contrib modules