aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/postmaster/checkpointer.c4
-rw-r--r--src/backend/postmaster/interrupt.c5
-rw-r--r--src/backend/postmaster/pgarch.c10
-rw-r--r--src/backend/postmaster/startup.c5
-rw-r--r--src/backend/postmaster/walwriter.c4
-rw-r--r--src/backend/utils/adt/mcxtfuncs.c38
-rw-r--r--src/test/regress/expected/misc_functions.out7
-rw-r--r--src/test/regress/sql/misc_functions.sql3
8 files changed, 62 insertions, 14 deletions
diff --git a/src/backend/postmaster/checkpointer.c b/src/backend/postmaster/checkpointer.c
index 940b773fe1b..23f691cd475 100644
--- a/src/backend/postmaster/checkpointer.c
+++ b/src/backend/postmaster/checkpointer.c
@@ -577,6 +577,10 @@ HandleCheckpointerInterrupts(void)
/* Normal exit from the checkpointer is here */
proc_exit(0); /* done */
}
+
+ /* Perform logging of memory contexts of this process */
+ if (LogMemoryContextPending)
+ ProcessLogMemoryContextInterrupt();
}
/*
diff --git a/src/backend/postmaster/interrupt.c b/src/backend/postmaster/interrupt.c
index b3db4f2a4c1..3f412dad2e6 100644
--- a/src/backend/postmaster/interrupt.c
+++ b/src/backend/postmaster/interrupt.c
@@ -22,6 +22,7 @@
#include "storage/latch.h"
#include "storage/procsignal.h"
#include "utils/guc.h"
+#include "utils/memutils.h"
volatile sig_atomic_t ConfigReloadPending = false;
volatile sig_atomic_t ShutdownRequestPending = false;
@@ -43,6 +44,10 @@ HandleMainLoopInterrupts(void)
if (ShutdownRequestPending)
proc_exit(0);
+
+ /* Perform logging of memory contexts of this process */
+ if (LogMemoryContextPending)
+ ProcessLogMemoryContextInterrupt();
}
/*
diff --git a/src/backend/postmaster/pgarch.c b/src/backend/postmaster/pgarch.c
index b319d032904..1121e4fb29c 100644
--- a/src/backend/postmaster/pgarch.c
+++ b/src/backend/postmaster/pgarch.c
@@ -50,6 +50,7 @@
#include "storage/shmem.h"
#include "storage/spin.h"
#include "utils/guc.h"
+#include "utils/memutils.h"
#include "utils/ps_status.h"
@@ -861,8 +862,9 @@ pgarch_die(int code, Datum arg)
* Interrupt handler for WAL archiver process.
*
* This is called in the loops pgarch_MainLoop and pgarch_ArchiverCopyLoop.
- * It checks for barrier events and config update, but not shutdown request
- * because how to handle shutdown request is different between those loops.
+ * It checks for barrier events, config update and request for logging of
+ * memory contexts, but not shutdown request because how to handle
+ * shutdown request is different between those loops.
*/
static void
HandlePgArchInterrupts(void)
@@ -875,4 +877,8 @@ HandlePgArchInterrupts(void)
ConfigReloadPending = false;
ProcessConfigFile(PGC_SIGHUP);
}
+
+ /* Perform logging of memory contexts of this process */
+ if (LogMemoryContextPending)
+ ProcessLogMemoryContextInterrupt();
}
diff --git a/src/backend/postmaster/startup.c b/src/backend/postmaster/startup.c
index e9518beedca..9bae16bfc78 100644
--- a/src/backend/postmaster/startup.c
+++ b/src/backend/postmaster/startup.c
@@ -32,6 +32,7 @@
#include "storage/procsignal.h"
#include "storage/standby.h"
#include "utils/guc.h"
+#include "utils/memutils.h"
#include "utils/timeout.h"
@@ -200,6 +201,10 @@ HandleStartupProcInterrupts(void)
/* Process barrier events */
if (ProcSignalBarrierPending)
ProcessProcSignalBarrier();
+
+ /* Perform logging of memory contexts of this process */
+ if (LogMemoryContextPending)
+ ProcessLogMemoryContextInterrupt();
}
diff --git a/src/backend/postmaster/walwriter.c b/src/backend/postmaster/walwriter.c
index 9db9d986539..102fa2a089f 100644
--- a/src/backend/postmaster/walwriter.c
+++ b/src/backend/postmaster/walwriter.c
@@ -306,4 +306,8 @@ HandleWalWriterInterrupts(void)
proc_exit(0);
}
+
+ /* Perform logging of memory contexts of this process */
+ if (LogMemoryContextPending)
+ ProcessLogMemoryContextInterrupt();
}
diff --git a/src/backend/utils/adt/mcxtfuncs.c b/src/backend/utils/adt/mcxtfuncs.c
index 845d619d605..28cb9d3ff10 100644
--- a/src/backend/utils/adt/mcxtfuncs.c
+++ b/src/backend/utils/adt/mcxtfuncs.c
@@ -160,33 +160,47 @@ pg_get_backend_memory_contexts(PG_FUNCTION_ARGS)
/*
* pg_log_backend_memory_contexts
- * Signal a backend process to log its memory contexts.
+ * Signal a backend or an auxiliary process to log its memory contexts.
*
* By default, only superusers are allowed to signal to log the memory
* contexts because allowing any users to issue this request at an unbounded
* rate would cause lots of log messages and which can lead to denial of
* service. Additional roles can be permitted with GRANT.
*
- * On receipt of this signal, a backend sets the flag in the signal
- * handler, which causes the next CHECK_FOR_INTERRUPTS() to log the
- * memory contexts.
+ * On receipt of this signal, a backend or an auxiliary process sets the flag
+ * in the signal handler, which causes the next CHECK_FOR_INTERRUPTS()
+ * or process-specific interrupt handler to log the memory contexts.
*/
Datum
pg_log_backend_memory_contexts(PG_FUNCTION_ARGS)
{
int pid = PG_GETARG_INT32(0);
PGPROC *proc;
+ BackendId backendId = InvalidBackendId;
proc = BackendPidGetProc(pid);
/*
- * 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.
+ * 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)
{
@@ -199,7 +213,7 @@ pg_log_backend_memory_contexts(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(false);
}
- if (SendProcSignal(pid, PROCSIG_LOG_MEMORY_CONTEXT, proc->backendId) < 0)
+ 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 1013d17f87d..e2c77d0ac84 100644
--- a/src/test/regress/expected/misc_functions.out
+++ b/src/test/regress/expected/misc_functions.out
@@ -147,6 +147,13 @@ SELECT pg_log_backend_memory_contexts(pg_backend_pid());
t
(1 row)
+SELECT pg_log_backend_memory_contexts(pid) FROM pg_stat_activity
+ WHERE backend_type = 'checkpointer';
+ pg_log_backend_memory_contexts
+--------------------------------
+ t
+(1 row)
+
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 7ab9b2a1509..1159f6b5855 100644
--- a/src/test/regress/sql/misc_functions.sql
+++ b/src/test/regress/sql/misc_functions.sql
@@ -41,6 +41,9 @@ SELECT num_nulls();
SELECT pg_log_backend_memory_contexts(pg_backend_pid());
+SELECT pg_log_backend_memory_contexts(pid) FROM pg_stat_activity
+ WHERE backend_type = 'checkpointer';
+
CREATE ROLE regress_log_memory;
SELECT has_function_privilege('regress_log_memory',