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 127bd9e7da3..45abf48768a 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 87dd289f626..59640bb4f97 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); @@ -724,6 +725,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. */ @@ -1101,6 +1110,25 @@ AuxiliaryProcKill(int code, Datum arg) SwitchBackToLocalLatch(); pgstat_reset_wait_event_storage(); + /* + * If this was one of the 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;