v13-0001-Refactor-how-some-aux-processes-advertise-their-.patch
text/x-patch
Filename: v13-0001-Refactor-how-some-aux-processes-advertise-their-.patch
Type: text/x-patch
Part: 0
Message:
Re: Interrupts vs signals
Patch
Format: format-patch
Series: patch v13-0001
Subject: Refactor how some aux processes advertise their ProcNumber
| File | + | − |
|---|---|---|
| src/backend/access/transam/xlog.c | 1 | 2 |
| src/backend/postmaster/autovacuum.c | 10 | 9 |
| src/backend/postmaster/checkpointer.c | 4 | 10 |
| src/backend/postmaster/walwriter.c | 0 | 6 |
| src/backend/storage/lmgr/proc.c | 28 | 2 |
| src/include/storage/proc.h | 4 | 3 |
From 6efef631c6747b8c60cdeae543b4cd91f06da2e4 Mon Sep 17 00:00:00 2001
From: Heikki Linnakangas <heikki.linnakangas@iki.fi>
Date: Fri, 13 Feb 2026 14:23:35 +0200
Subject: [PATCH v13 1/9] Refactor how some aux processes advertise their
ProcNumber
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/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 +++++++++++++++++++++++++--
src/include/storage/proc.h | 7 ++++---
6 files changed, 47 insertions(+), 32 deletions(-)
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index a81912b7441..a8bbf6284a7 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -2671,8 +2671,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 e9aaf24c1be..777acaa7c84 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -286,7 +286,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
@@ -302,7 +301,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;
@@ -602,8 +600,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
@@ -837,8 +833,6 @@ AutoVacLauncherShutdown(void)
{
ereport(DEBUG1,
(errmsg_internal("autovacuum launcher shutting down")));
- AutoVacuumShmem->av_launcherpid = 0;
-
proc_exit(0); /* done */
}
@@ -1569,6 +1563,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;
@@ -1587,8 +1583,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
{
@@ -3559,7 +3561,6 @@ AutoVacuumShmemInit(void *arg)
{
WorkerInfo worker;
- 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 087120db090..a09d4097d51 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"
@@ -358,12 +359,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.
@@ -1120,7 +1115,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)
{
@@ -1261,8 +1256,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);
@@ -1543,7 +1537,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 af24d05c542..68dd5047c20 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 6fa9de33e1c..28c0efc3e20 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -240,8 +240,9 @@ ProcGlobalShmemInit(void *arg)
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);
@@ -725,6 +726,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.
*/
@@ -1102,6 +1111,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;
diff --git a/src/include/storage/proc.h b/src/include/storage/proc.h
index 3e1d1fad5f9..0314f979e60 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;
--
2.47.3