mirror of
https://github.com/postgres/postgres.git
synced 2025-05-09 18:21:05 +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:
parent
85ec945b78
commit
2bbc261ddb
@ -24,6 +24,7 @@
|
|||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
#include "postmaster/postmaster.h"
|
#include "postmaster/postmaster.h"
|
||||||
#include "replication/walsender.h"
|
#include "replication/walsender.h"
|
||||||
|
#include "storage/ipc.h"
|
||||||
#include "storage/pmsignal.h"
|
#include "storage/pmsignal.h"
|
||||||
#include "storage/shmem.h"
|
#include "storage/shmem.h"
|
||||||
#include "utils/memutils.h"
|
#include "utils/memutils.h"
|
||||||
@ -121,6 +122,8 @@ postmaster_death_handler(SIGNAL_ARGS)
|
|||||||
|
|
||||||
#endif /* USE_POSTMASTER_DEATH_SIGNAL */
|
#endif /* USE_POSTMASTER_DEATH_SIGNAL */
|
||||||
|
|
||||||
|
static void MarkPostmasterChildInactive(int code, Datum arg);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PMSignalShmemSize
|
* PMSignalShmemSize
|
||||||
* Compute space needed for pmsignal.c's shared memory
|
* 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.
|
* 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
|
void
|
||||||
MarkPostmasterChildActive(void)
|
RegisterPostmasterChildActive(void)
|
||||||
{
|
{
|
||||||
int slot = MyPMChildSlot;
|
int slot = MyPMChildSlot;
|
||||||
|
|
||||||
@ -328,6 +334,9 @@ MarkPostmasterChildActive(void)
|
|||||||
slot--;
|
slot--;
|
||||||
Assert(PMSignalState->PMChildFlags[slot] == PM_CHILD_ASSIGNED);
|
Assert(PMSignalState->PMChildFlags[slot] == PM_CHILD_ASSIGNED);
|
||||||
PMSignalState->PMChildFlags[slot] = PM_CHILD_ACTIVE;
|
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
|
* MarkPostmasterChildInactive - mark a postmaster child as done using
|
||||||
* shared memory. This is called in the child process.
|
* shared memory. This is called in the child process.
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
MarkPostmasterChildInactive(void)
|
MarkPostmasterChildInactive(int code, Datum arg)
|
||||||
{
|
{
|
||||||
int slot = MyPMChildSlot;
|
int slot = MyPMChildSlot;
|
||||||
|
|
||||||
|
@ -354,6 +354,19 @@ InitProcess(void)
|
|||||||
if (MyProc != NULL)
|
if (MyProc != NULL)
|
||||||
elog(ERROR, "you already exist");
|
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. */
|
/* Decide which list should supply our PGPROC. */
|
||||||
if (AmAutoVacuumLauncherProcess() || AmAutoVacuumWorkerProcess())
|
if (AmAutoVacuumLauncherProcess() || AmAutoVacuumWorkerProcess())
|
||||||
procgloballist = &ProcGlobal->autovacFreeProcs;
|
procgloballist = &ProcGlobal->autovacFreeProcs;
|
||||||
@ -406,19 +419,6 @@ InitProcess(void)
|
|||||||
*/
|
*/
|
||||||
Assert(MyProc->procgloballist == procgloballist);
|
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
|
* Initialize all fields of MyProc, except for those previously
|
||||||
* initialized by InitProcGlobal.
|
* initialized by InitProcGlobal.
|
||||||
@ -993,18 +993,6 @@ ProcKill(int code, Datum arg)
|
|||||||
|
|
||||||
SpinLockRelease(ProcStructLock);
|
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 */
|
/* wake autovac launcher if needed -- see comments in FreeWorkerInfo */
|
||||||
if (AutovacuumLauncherPid != 0)
|
if (AutovacuumLauncherPid != 0)
|
||||||
kill(AutovacuumLauncherPid, SIGUSR2);
|
kill(AutovacuumLauncherPid, SIGUSR2);
|
||||||
|
@ -73,8 +73,7 @@ extern QuitSignalReason GetQuitSignalReason(void);
|
|||||||
extern int AssignPostmasterChildSlot(void);
|
extern int AssignPostmasterChildSlot(void);
|
||||||
extern bool ReleasePostmasterChildSlot(int slot);
|
extern bool ReleasePostmasterChildSlot(int slot);
|
||||||
extern bool IsPostmasterChildWalSender(int slot);
|
extern bool IsPostmasterChildWalSender(int slot);
|
||||||
extern void MarkPostmasterChildActive(void);
|
extern void RegisterPostmasterChildActive(void);
|
||||||
extern void MarkPostmasterChildInactive(void);
|
|
||||||
extern void MarkPostmasterChildWalSender(void);
|
extern void MarkPostmasterChildWalSender(void);
|
||||||
extern bool PostmasterIsAliveInternal(void);
|
extern bool PostmasterIsAliveInternal(void);
|
||||||
extern void PostmasterDeathSignalInit(void);
|
extern void PostmasterDeathSignalInit(void);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user