1
0
mirror of https://github.com/postgres/postgres.git synced 2025-05-06 19:59:18 +03:00

Use an shmem_exit callback to remove backend from PMChildFlags on exit

This seems nicer than having to duplicate the logic between
InitProcess() and ProcKill() for which child processes have a
PMChildFlags slot.

Move the MarkPostmasterChildActive() call earlier in InitProcess(),
out of the section protected by the spinlock.

Reviewed-by: Andres Freund <andres@anarazel.de>
Discussion: https://www.postgresql.org/message-id/a102f15f-eac4-4ff2-af02-f9ff209ec66f@iki.fi
This commit is contained in:
Heikki Linnakangas 2024-10-08 15:06:34 +03:00
parent 85ec945b78
commit 2bbc261ddb
3 changed files with 27 additions and 31 deletions

View File

@ -24,6 +24,7 @@
#include "miscadmin.h"
#include "postmaster/postmaster.h"
#include "replication/walsender.h"
#include "storage/ipc.h"
#include "storage/pmsignal.h"
#include "storage/shmem.h"
#include "utils/memutils.h"
@ -121,6 +122,8 @@ postmaster_death_handler(SIGNAL_ARGS)
#endif /* USE_POSTMASTER_DEATH_SIGNAL */
static void MarkPostmasterChildInactive(int code, Datum arg);
/*
* PMSignalShmemSize
* Compute space needed for pmsignal.c's shared memory
@ -316,11 +319,14 @@ IsPostmasterChildWalSender(int slot)
}
/*
* MarkPostmasterChildActive - mark a postmaster child as about to begin
* RegisterPostmasterChildActive - mark a postmaster child as about to begin
* actively using shared memory. This is called in the child process.
*
* This register an shmem exit hook to mark us as inactive again when the
* process exits normally.
*/
void
MarkPostmasterChildActive(void)
RegisterPostmasterChildActive(void)
{
int slot = MyPMChildSlot;
@ -328,6 +334,9 @@ MarkPostmasterChildActive(void)
slot--;
Assert(PMSignalState->PMChildFlags[slot] == PM_CHILD_ASSIGNED);
PMSignalState->PMChildFlags[slot] = PM_CHILD_ACTIVE;
/* Arrange to clean up at exit. */
on_shmem_exit(MarkPostmasterChildInactive, 0);
}
/*
@ -352,8 +361,8 @@ MarkPostmasterChildWalSender(void)
* MarkPostmasterChildInactive - mark a postmaster child as done using
* shared memory. This is called in the child process.
*/
void
MarkPostmasterChildInactive(void)
static void
MarkPostmasterChildInactive(int code, Datum arg)
{
int slot = MyPMChildSlot;

View File

@ -354,6 +354,19 @@ InitProcess(void)
if (MyProc != NULL)
elog(ERROR, "you already exist");
/*
* Before we start accessing the shared memory in a serious way, mark
* ourselves as an active postmaster child; this is so that the postmaster
* can detect it if we exit without cleaning up. (XXX autovac launcher
* currently doesn't participate in this; it probably should.)
*
* Slot sync worker also does not participate in it, see comments atop
* 'struct bkend' in postmaster.c.
*/
if (IsUnderPostmaster && !AmAutoVacuumLauncherProcess() &&
!AmLogicalSlotSyncWorkerProcess())
RegisterPostmasterChildActive();
/* Decide which list should supply our PGPROC. */
if (AmAutoVacuumLauncherProcess() || AmAutoVacuumWorkerProcess())
procgloballist = &ProcGlobal->autovacFreeProcs;
@ -406,19 +419,6 @@ InitProcess(void)
*/
Assert(MyProc->procgloballist == procgloballist);
/*
* Now that we have a PGPROC, mark ourselves as an active postmaster
* child; this is so that the postmaster can detect it if we exit without
* cleaning up. (XXX autovac launcher currently doesn't participate in
* this; it probably should.)
*
* Slot sync worker also does not participate in it, see comments atop
* 'struct bkend' in postmaster.c.
*/
if (IsUnderPostmaster && !AmAutoVacuumLauncherProcess() &&
!AmLogicalSlotSyncWorkerProcess())
MarkPostmasterChildActive();
/*
* Initialize all fields of MyProc, except for those previously
* initialized by InitProcGlobal.
@ -993,18 +993,6 @@ ProcKill(int code, Datum arg)
SpinLockRelease(ProcStructLock);
/*
* This process is no longer present in shared memory in any meaningful
* way, so tell the postmaster we've cleaned up acceptably well. (XXX
* autovac launcher should be included here someday)
*
* Slot sync worker is also not a postmaster child, so skip this shared
* memory related processing here.
*/
if (IsUnderPostmaster && !AmAutoVacuumLauncherProcess() &&
!AmLogicalSlotSyncWorkerProcess())
MarkPostmasterChildInactive();
/* wake autovac launcher if needed -- see comments in FreeWorkerInfo */
if (AutovacuumLauncherPid != 0)
kill(AutovacuumLauncherPid, SIGUSR2);

View File

@ -73,8 +73,7 @@ extern QuitSignalReason GetQuitSignalReason(void);
extern int AssignPostmasterChildSlot(void);
extern bool ReleasePostmasterChildSlot(int slot);
extern bool IsPostmasterChildWalSender(int slot);
extern void MarkPostmasterChildActive(void);
extern void MarkPostmasterChildInactive(void);
extern void RegisterPostmasterChildActive(void);
extern void MarkPostmasterChildWalSender(void);
extern bool PostmasterIsAliveInternal(void);
extern void PostmasterDeathSignalInit(void);