From e5ac2524ac6781bbc552269b06e157bdb0d1db86 Mon Sep 17 00:00:00 2001 From: Bharath Rupireddy Date: Fri, 29 Oct 2021 16:42:18 +0000 Subject: [PATCH v1] enhance pg_log_backend_memory_contexts to log memory contexts of aux procs Currently pg_log_backend_memory_contexts() doesn't log the memory contexts of auxiliary processes such as bgwriter, checkpointer, wal writer, archiver, startup process and wal receiver. It will be useful to look at the memory contexts of these processes too, for debugging purposes and better understanding of the memory usage pattern of these processes. Inside the code, we could use the AuxiliaryPidGetProc() to get the PGPROC of these processes. Note that, neither AuxiliaryPidGetProc() nor BackendPidGetProc() can return PGPROC(as they don't have PGPROC entries at all) entries for the syslogger, stats collector processes. --- doc/src/sgml/func.sgml | 14 +++++--- src/backend/utils/adt/mcxtfuncs.c | 29 +++++++++++----- src/test/regress/expected/misc_functions.out | 35 ++++++++++++++++++++ src/test/regress/sql/misc_functions.sql | 13 ++++++++ 4 files changed, 79 insertions(+), 12 deletions(-) diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 4b49dff2ff..2449434abf 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -25325,10 +25325,16 @@ SELECT collation for ('foo' COLLATE "de_DE"); boolean - Requests to log the memory contexts of the backend with the - specified process ID. These memory contexts will be logged at - LOG message level. They will appear in - the server log based on the log configuration set + Requests to log memory contexts of the backend or the + WAL sender or + the auxiliary process + with the specified process ID. All of the + auxiliary processes + are supported except the logger + and the statistics collector + as they are not connected to shared memory the function can not make requests. + These memory contexts will be logged at LOG message level. + They will appear in the server log based on the log configuration set (See for more information), but will not be sent to the client regardless of . diff --git a/src/backend/utils/adt/mcxtfuncs.c b/src/backend/utils/adt/mcxtfuncs.c index 6ddbf70b30..67598ddbb3 100644 --- a/src/backend/utils/adt/mcxtfuncs.c +++ b/src/backend/utils/adt/mcxtfuncs.c @@ -176,17 +176,26 @@ pg_log_backend_memory_contexts(PG_FUNCTION_ARGS) { int pid = PG_GETARG_INT32(0); PGPROC *proc; + bool is_aux_proc = false; + BackendId backendId = InvalidBackendId; proc = BackendPidGetProc(pid); + /* See if the process with given pid is an auxiliary process. */ + if (proc == NULL) + { + proc = AuxiliaryPidGetProc(pid); + is_aux_proc = true; + } + /* - * BackendPidGetProc returns 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 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. + * BackendPidGetProc or AuxiliaryPidGetProc returns 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 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) { @@ -199,7 +208,11 @@ pg_log_backend_memory_contexts(PG_FUNCTION_ARGS) PG_RETURN_BOOL(false); } - if (SendProcSignal(pid, PROCSIG_LOG_MEMORY_CONTEXT, proc->backendId) < 0) + /* Only regular backends will have valid backend id, auxiliary processes don't. */ + if (!is_aux_proc) + backendId = proc->backendId; + + if (SendProcSignal(pid, PROCSIG_LOG_MEMORY_CONTEXT, backendId) < 0) { /* Again, just a warning to allow loops */ ereport(WARNING, diff --git a/src/test/regress/expected/misc_functions.out b/src/test/regress/expected/misc_functions.out index 71d316cad3..f2a0965e2d 100644 --- a/src/test/regress/expected/misc_functions.out +++ b/src/test/regress/expected/misc_functions.out @@ -147,6 +147,41 @@ SELECT pg_log_backend_memory_contexts(pg_backend_pid()); t (1 row) +CREATE FUNCTION memcxt_get_proc_pid(text) +RETURNS int +LANGUAGE SQL +AS 'SELECT pid FROM pg_stat_activity WHERE backend_type = $1'; +SELECT pg_log_backend_memory_contexts(memcxt_get_proc_pid('autovacuum launcher')); + pg_log_backend_memory_contexts +-------------------------------- + t +(1 row) + +SELECT pg_log_backend_memory_contexts(memcxt_get_proc_pid('logical replication launcher')); + pg_log_backend_memory_contexts +-------------------------------- + t +(1 row) + +SELECT pg_log_backend_memory_contexts(memcxt_get_proc_pid('background writer')); + pg_log_backend_memory_contexts +-------------------------------- + t +(1 row) + +SELECT pg_log_backend_memory_contexts(memcxt_get_proc_pid('checkpointer')); + pg_log_backend_memory_contexts +-------------------------------- + t +(1 row) + +SELECT pg_log_backend_memory_contexts(memcxt_get_proc_pid('walwriter')); + pg_log_backend_memory_contexts +-------------------------------- + t +(1 row) + +DROP FUNCTION memcxt_get_proc_pid(text); CREATE ROLE regress_log_memory; SELECT has_function_privilege('regress_log_memory', 'pg_log_backend_memory_contexts(integer)', 'EXECUTE'); -- no diff --git a/src/test/regress/sql/misc_functions.sql b/src/test/regress/sql/misc_functions.sql index 8c23874b3f..c87455c937 100644 --- a/src/test/regress/sql/misc_functions.sql +++ b/src/test/regress/sql/misc_functions.sql @@ -41,6 +41,19 @@ SELECT num_nulls(); SELECT pg_log_backend_memory_contexts(pg_backend_pid()); +CREATE FUNCTION memcxt_get_proc_pid(text) +RETURNS int +LANGUAGE SQL +AS 'SELECT pid FROM pg_stat_activity WHERE backend_type = $1'; + +SELECT pg_log_backend_memory_contexts(memcxt_get_proc_pid('autovacuum launcher')); +SELECT pg_log_backend_memory_contexts(memcxt_get_proc_pid('logical replication launcher')); +SELECT pg_log_backend_memory_contexts(memcxt_get_proc_pid('background writer')); +SELECT pg_log_backend_memory_contexts(memcxt_get_proc_pid('checkpointer')); +SELECT pg_log_backend_memory_contexts(memcxt_get_proc_pid('walwriter')); + +DROP FUNCTION memcxt_get_proc_pid(text); + CREATE ROLE regress_log_memory; SELECT has_function_privilege('regress_log_memory', -- 2.25.1