Thread

  1. [PATCH v12a 1/4] Refactor how some aux processes advertise their ProcNumber

    Heikki Linnakangas <heikki.linnakangas@iki.fi> — 2026-02-13T12:23:35Z

    This moves the responsibility of setting the
    ProcGlobal->walrewriterProc and checkpointerProc fields to
    InitAuxiliaryProcess. Also switch to the same pattern to advertise the
    autovacuum launcher's ProcNumber, replacing the ad hoc av_launcherpid
    field in shared memory. This can easily be extended to other aux
    processes in the future, if other processes need to find them.
    
    Switch to pg_atomic_uint32 for the fields. Seems easier to reason
    about than volatile pointers. There was some precedence for that, as
    were already using pg_atomic_uint32 for the procArrayGroupFirst and
    clogGroupFirst fields, which also store ProcNumbers.
    
    TODO: could also replace WalRecv->procno with this
    ---
     src/include/storage/proc.h            |  7 ++++---
     src/backend/access/transam/xlog.c     |  3 +--
     src/backend/postmaster/autovacuum.c   | 19 +++++++++--------
     src/backend/postmaster/checkpointer.c | 14 ++++---------
     src/backend/postmaster/walwriter.c    |  6 ------
     src/backend/storage/lmgr/proc.c       | 30 +++++++++++++++++++++++++--
     6 files changed, 47 insertions(+), 32 deletions(-)
    
    diff --git a/src/include/storage/proc.h b/src/include/storage/proc.h
    index 3f89450c216..4a1fafb9038 100644
    --- a/src/include/storage/proc.h
    +++ b/src/include/storage/proc.h
    @@ -488,11 +488,12 @@ typedef struct PROC_HDR
     	pg_atomic_uint32 clogGroupFirst;
     
     	/*
    -	 * Current slot numbers of some auxiliary processes. There can be only one
    +	 * Current proc numbers of some auxiliary processes. There can be only one
     	 * of each of these running at a time.
     	 */
    -	ProcNumber	walwriterProc;
    -	ProcNumber	checkpointerProc;
    +	pg_atomic_uint32 avLauncherProc;
    +	pg_atomic_uint32 walwriterProc;
    +	pg_atomic_uint32 checkpointerProc;
     
     	/* Current shared estimate of appropriate spins_per_delay value */
     	int			spins_per_delay;
    diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
    index b9b678f3722..0b5ad4dc79c 100644
    --- a/src/backend/access/transam/xlog.c
    +++ b/src/backend/access/transam/xlog.c
    @@ -2637,8 +2637,7 @@ XLogSetAsyncXactLSN(XLogRecPtr asyncXactLSN)
     
     	if (wakeup)
     	{
    -		volatile PROC_HDR *procglobal = ProcGlobal;
    -		ProcNumber	walwriterProc = procglobal->walwriterProc;
    +		ProcNumber	walwriterProc = pg_atomic_read_u32(&ProcGlobal->walwriterProc);
     
     		if (walwriterProc != INVALID_PROC_NUMBER)
     			SetLatch(&GetPGProcByNumber(walwriterProc)->procLatch);
    diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
    index 695e187ba11..74574e1eaf9 100644
    --- a/src/backend/postmaster/autovacuum.c
    +++ b/src/backend/postmaster/autovacuum.c
    @@ -278,7 +278,6 @@ typedef struct AutoVacuumWorkItem
      * struct and the array of WorkerInfo structs.  This struct keeps:
      *
      * av_signal		set by other processes to indicate various conditions
    - * av_launcherpid	the PID of the autovacuum launcher
      * av_freeWorkers	the WorkerInfo freelist
      * av_runningWorkers the WorkerInfo non-free queue
      * av_startingWorker pointer to WorkerInfo currently being started (cleared by
    @@ -294,7 +293,6 @@ typedef struct AutoVacuumWorkItem
     typedef struct
     {
     	sig_atomic_t av_signal[AutoVacNumSignals];
    -	pid_t		av_launcherpid;
     	dclist_head av_freeWorkers;
     	dlist_head	av_runningWorkers;
     	WorkerInfo	av_startingWorker;
    @@ -565,8 +563,6 @@ AutoVacLauncherMain(const void *startup_data, size_t startup_data_len)
     		proc_exit(0);			/* done */
     	}
     
    -	AutoVacuumShmem->av_launcherpid = MyProcPid;
    -
     	/*
     	 * Create the initial database list.  The invariant we want this list to
     	 * keep is that it's ordered by decreasing next_worker.  As soon as an
    @@ -800,8 +796,6 @@ AutoVacLauncherShutdown(void)
     {
     	ereport(DEBUG1,
     			(errmsg_internal("autovacuum launcher shutting down")));
    -	AutoVacuumShmem->av_launcherpid = 0;
    -
     	proc_exit(0);				/* done */
     }
     
    @@ -1532,6 +1526,8 @@ AutoVacWorkerMain(const void *startup_data, size_t startup_data_len)
     	 */
     	if (AutoVacuumShmem->av_startingWorker != NULL)
     	{
    +		ProcNumber	launcherProc;
    +
     		MyWorkerInfo = AutoVacuumShmem->av_startingWorker;
     		dbid = MyWorkerInfo->wi_dboid;
     		MyWorkerInfo->wi_proc = MyProc;
    @@ -1550,8 +1546,14 @@ AutoVacWorkerMain(const void *startup_data, size_t startup_data_len)
     		on_shmem_exit(FreeWorkerInfo, 0);
     
     		/* wake up the launcher */
    -		if (AutoVacuumShmem->av_launcherpid != 0)
    -			kill(AutoVacuumShmem->av_launcherpid, SIGUSR2);
    +		launcherProc = pg_atomic_read_u32(&ProcGlobal->avLauncherProc);
    +		if (launcherProc != INVALID_PROC_NUMBER)
    +		{
    +			int			pid = GetPGProcByNumber(launcherProc)->pid;
    +
    +			if (pid != 0)
    +				kill(pid, SIGUSR2);
    +		}
     	}
     	else
     	{
    @@ -3394,7 +3396,6 @@ AutoVacuumShmemInit(void)
     
     		Assert(!found);
     
    -		AutoVacuumShmem->av_launcherpid = 0;
     		dclist_init(&AutoVacuumShmem->av_freeWorkers);
     		dlist_init(&AutoVacuumShmem->av_runningWorkers);
     		AutoVacuumShmem->av_startingWorker = NULL;
    diff --git a/src/backend/postmaster/checkpointer.c b/src/backend/postmaster/checkpointer.c
    index 3c982c6ffac..e4075265495 100644
    --- a/src/backend/postmaster/checkpointer.c
    +++ b/src/backend/postmaster/checkpointer.c
    @@ -47,6 +47,7 @@
     #include "libpq/pqsignal.h"
     #include "miscadmin.h"
     #include "pgstat.h"
    +#include "port/atomics.h"
     #include "postmaster/auxprocess.h"
     #include "postmaster/bgwriter.h"
     #include "postmaster/interrupt.h"
    @@ -349,12 +350,6 @@ CheckpointerMain(const void *startup_data, size_t startup_data_len)
     	 */
     	UpdateSharedMemoryConfig();
     
    -	/*
    -	 * Advertise our proc number that backends can use to wake us up while
    -	 * we're sleeping.
    -	 */
    -	ProcGlobal->checkpointerProc = MyProcNumber;
    -
     	/*
     	 * Loop until we've been asked to write the shutdown checkpoint or
     	 * terminate.
    @@ -1126,7 +1121,7 @@ RequestCheckpoint(int flags)
     	for (ntries = 0;; ntries++)
     	{
     		volatile PROC_HDR *procglobal = ProcGlobal;
    -		ProcNumber	checkpointerProc = procglobal->checkpointerProc;
    +		ProcNumber	checkpointerProc = pg_atomic_read_u32(&procglobal->checkpointerProc);
     
     		if (checkpointerProc == INVALID_PROC_NUMBER)
     		{
    @@ -1267,8 +1262,7 @@ ForwardSyncRequest(const FileTag *ftag, SyncRequestType type)
     	/* ... but not till after we release the lock */
     	if (too_full)
     	{
    -		volatile PROC_HDR *procglobal = ProcGlobal;
    -		ProcNumber	checkpointerProc = procglobal->checkpointerProc;
    +		ProcNumber	checkpointerProc = pg_atomic_read_u32(&ProcGlobal->checkpointerProc);
     
     		if (checkpointerProc != INVALID_PROC_NUMBER)
     			SetLatch(&GetPGProcByNumber(checkpointerProc)->procLatch);
    @@ -1549,7 +1543,7 @@ void
     WakeupCheckpointer(void)
     {
     	volatile PROC_HDR *procglobal = ProcGlobal;
    -	ProcNumber	checkpointerProc = procglobal->checkpointerProc;
    +	ProcNumber	checkpointerProc = pg_atomic_read_u32(&procglobal->checkpointerProc);
     
     	if (checkpointerProc != INVALID_PROC_NUMBER)
     		SetLatch(&GetPGProcByNumber(checkpointerProc)->procLatch);
    diff --git a/src/backend/postmaster/walwriter.c b/src/backend/postmaster/walwriter.c
    index 9cd86ad7022..2c3b4f831aa 100644
    --- a/src/backend/postmaster/walwriter.c
    +++ b/src/backend/postmaster/walwriter.c
    @@ -206,12 +206,6 @@ WalWriterMain(const void *startup_data, size_t startup_data_len)
     	hibernating = false;
     	SetWalWriterSleeping(false);
     
    -	/*
    -	 * Advertise our proc number that backends can use to wake us up while
    -	 * we're sleeping.
    -	 */
    -	ProcGlobal->walwriterProc = MyProcNumber;
    -
     	/*
     	 * Loop forever
     	 */
    diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
    index daf70d9ce2a..2c241cb0244 100644
    --- a/src/backend/storage/lmgr/proc.c
    +++ b/src/backend/storage/lmgr/proc.c
    @@ -212,8 +212,9 @@ InitProcGlobal(void)
     	dlist_init(&ProcGlobal->bgworkerFreeProcs);
     	dlist_init(&ProcGlobal->walsenderFreeProcs);
     	ProcGlobal->startupBufferPinWaitBufId = -1;
    -	ProcGlobal->walwriterProc = INVALID_PROC_NUMBER;
    -	ProcGlobal->checkpointerProc = INVALID_PROC_NUMBER;
    +	pg_atomic_init_u32(&ProcGlobal->avLauncherProc, INVALID_PROC_NUMBER);
    +	pg_atomic_init_u32(&ProcGlobal->walwriterProc, INVALID_PROC_NUMBER);
    +	pg_atomic_init_u32(&ProcGlobal->checkpointerProc, INVALID_PROC_NUMBER);
     	pg_atomic_init_u32(&ProcGlobal->procArrayGroupFirst, INVALID_PROC_NUMBER);
     	pg_atomic_init_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER);
     
    @@ -712,6 +713,14 @@ InitAuxiliaryProcess(void)
     	 */
     	PGSemaphoreReset(MyProc->sem);
     
    +	/* Some aux processes are also advertised in ProcGlobal */
    +	if (MyBackendType == B_AUTOVAC_LAUNCHER)
    +		pg_atomic_write_u32(&ProcGlobal->avLauncherProc, MyProcNumber);
    +	if (MyBackendType == B_WAL_WRITER)
    +		pg_atomic_write_u32(&ProcGlobal->walwriterProc, MyProcNumber);
    +	if (MyBackendType == B_CHECKPOINTER)
    +		pg_atomic_write_u32(&ProcGlobal->checkpointerProc, MyProcNumber);
    +
     	/*
     	 * Arrange to clean up at process exit.
     	 */
    @@ -1056,6 +1065,23 @@ AuxiliaryProcKill(int code, Datum arg)
     	SwitchBackToLocalLatch();
     	pgstat_reset_wait_event_storage();
     
    +	/* If this was one of aux processes advertised in ProcGlobal, clear it */
    +	if (MyBackendType == B_AUTOVAC_LAUNCHER)
    +	{
    +		Assert(pg_atomic_read_u32(&ProcGlobal->avLauncherProc) == MyProcNumber);
    +		pg_atomic_write_u32(&ProcGlobal->avLauncherProc, INVALID_PROC_NUMBER);
    +	}
    +	if (MyBackendType == B_WAL_WRITER)
    +	{
    +		Assert(pg_atomic_read_u32(&ProcGlobal->walwriterProc) == MyProcNumber);
    +		pg_atomic_write_u32(&ProcGlobal->walwriterProc, INVALID_PROC_NUMBER);
    +	}
    +	if (MyBackendType == B_CHECKPOINTER)
    +	{
    +		Assert(pg_atomic_read_u32(&ProcGlobal->checkpointerProc) == MyProcNumber);
    +		pg_atomic_write_u32(&ProcGlobal->checkpointerProc, INVALID_PROC_NUMBER);
    +	}
    +
     	proc = MyProc;
     	MyProc = NULL;
     	MyProcNumber = INVALID_PROC_NUMBER;
    -- 
    2.53.0.1.gb2826b52eb
    
    
    --3rzmtywijtp4k7v2
    Content-Type: text/x-diff; charset=us-ascii
    Content-Disposition: attachment;
    	filename="v12a-0002-Centralize-resetting-SIGCHLD-handler.patch"