From ee5c26f0d4e2e211166250857ea42d30a3666709 Mon Sep 17 00:00:00 2001 From: Bharath Rupireddy Date: Wed, 11 Jan 2023 13:32:13 +0000 Subject: [PATCH v23] Move sending multiplexed-SIGUSR1 signal code to a function Add a new function hosting the common code for sending multiplexed-SIGUSR1 signal to a backend process. This function will also be used as-is by an upcoming commit reducing the code duplication. --- src/backend/storage/ipc/procarray.c | 60 +++++++++++++++++++++++++++++ src/backend/utils/adt/mcxtfuncs.c | 49 ++--------------------- src/include/storage/procarray.h | 1 + 3 files changed, 64 insertions(+), 46 deletions(-) diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c index 4340bf9641..5681f0d3b0 100644 --- a/src/backend/storage/ipc/procarray.c +++ b/src/backend/storage/ipc/procarray.c @@ -3151,6 +3151,66 @@ HaveVirtualXIDsDelayingChkpt(VirtualTransactionId *vxids, int nvxids, int type) return result; } +/* + * SendProcSignalBackendOrAuxproc -- check if the process with given pid is a + * backend or an auxiliary process and send it the SIGUSR1 signal for a given + * reason. + * + * Returns true if sending the signal was successful, false otherwise. + */ +bool +SendProcSignalBackendOrAuxproc(int pid, ProcSignalReason reason) +{ + PGPROC *proc; + BackendId backendId = InvalidBackendId; + + proc = BackendPidGetProc(pid); + + /* + * See if the process with given pid is a backend or an auxiliary process. + * + * If the given process is a backend, use its backend id in + * SendProcSignal() later to speed up the operation. Otherwise, don't do + * that because auxiliary processes (except the startup process) don't + * have a valid backend id. + */ + if (proc != NULL) + backendId = proc->backendId; + else + proc = AuxiliaryPidGetProc(pid); + + /* + * BackendPidGetProc() and AuxiliaryPidGetProc() return NULL if the pid + * isn't valid; but by the time we reach kill(), a process for which we + * get a valid proc here might have terminated on its own. There's no way + * to acquire a lock on an arbitrary process to prevent that. But since + * this mechanism is usually used to debug a backend or an auxiliary + * process running and consuming lots of memory or a long running process, + * that it might end on its own first and its memory contexts are not + * logged or backtrace not logged is not a problem. + */ + if (proc == NULL) + { + /* + * This is just a warning so a loop-through-resultset will not abort + * if one backend terminated on its own during the run. + */ + ereport(WARNING, + (errmsg("PID %d is not a PostgreSQL server process", pid))); + return false; + } + + if (SendProcSignal(pid, reason, backendId) < 0) + { + /* Again, just a warning to allow loops */ + ereport(WARNING, + (errmsg("could not send signal to process %d: %m", pid))); + return false; + } + + return true; +} + /* * BackendPidGetProc -- get a backend's PGPROC given its PID * diff --git a/src/backend/utils/adt/mcxtfuncs.c b/src/backend/utils/adt/mcxtfuncs.c index 92ca5b2f72..7b17afc2ff 100644 --- a/src/backend/utils/adt/mcxtfuncs.c +++ b/src/backend/utils/adt/mcxtfuncs.c @@ -145,51 +145,8 @@ Datum pg_log_backend_memory_contexts(PG_FUNCTION_ARGS) { int pid = PG_GETARG_INT32(0); - PGPROC *proc; - BackendId backendId = InvalidBackendId; + bool result; - proc = BackendPidGetProc(pid); - - /* - * See if the process with given pid is a backend or an auxiliary process. - * - * If the given process is a backend, use its backend id in - * SendProcSignal() later to speed up the operation. Otherwise, don't do - * that because auxiliary processes (except the startup process) don't - * have a valid backend id. - */ - if (proc != NULL) - backendId = proc->backendId; - else - proc = AuxiliaryPidGetProc(pid); - - /* - * BackendPidGetProc() and AuxiliaryPidGetProc() return NULL if the pid - * isn't valid; but by the time we reach kill(), a process for which we - * get a valid proc here might have terminated on its own. There's no way - * to acquire a lock on an arbitrary process to prevent that. But since - * this mechanism is usually used to debug a backend or an auxiliary - * process running and consuming lots of memory, that it might end on its - * own first and its memory contexts are not logged is not a problem. - */ - if (proc == NULL) - { - /* - * This is just a warning so a loop-through-resultset will not abort - * if one backend terminated on its own during the run. - */ - ereport(WARNING, - (errmsg("PID %d is not a PostgreSQL server process", pid))); - PG_RETURN_BOOL(false); - } - - if (SendProcSignal(pid, PROCSIG_LOG_MEMORY_CONTEXT, backendId) < 0) - { - /* Again, just a warning to allow loops */ - ereport(WARNING, - (errmsg("could not send signal to process %d: %m", pid))); - PG_RETURN_BOOL(false); - } - - PG_RETURN_BOOL(true); + result = SendProcSignalBackendOrAuxproc(pid, PROCSIG_LOG_MEMORY_CONTEXT); + PG_RETURN_BOOL(result); } diff --git a/src/include/storage/procarray.h b/src/include/storage/procarray.h index d8cae3ce1c..2b470ddadf 100644 --- a/src/include/storage/procarray.h +++ b/src/include/storage/procarray.h @@ -68,6 +68,7 @@ extern PGPROC *BackendPidGetProc(int pid); extern PGPROC *BackendPidGetProcWithLock(int pid); extern int BackendXidGetPid(TransactionId xid); extern bool IsBackendPid(int pid); +extern bool SendProcSignalBackendOrAuxproc(int pid, ProcSignalReason reason); extern VirtualTransactionId *GetCurrentVirtualXIDs(TransactionId limitXmin, bool excludeXmin0, bool allDbs, int excludeVacuum, -- 2.34.1