diff options
author | Daniel Gustafsson <dgustafsson@postgresql.org> | 2025-04-08 11:06:56 +0200 |
---|---|---|
committer | Daniel Gustafsson <dgustafsson@postgresql.org> | 2025-04-08 11:06:56 +0200 |
commit | 042a66291b04f473cbc72f95f07438abd75ae3a9 (patch) | |
tree | 730314170d4743e6dc62a128c4f3ff2f17797595 /src/include/utils/memutils.h | |
parent | 15f0cb26b530b6725a37391738cfc62d4745c49b (diff) | |
download | postgresql-042a66291b04f473cbc72f95f07438abd75ae3a9.tar.gz postgresql-042a66291b04f473cbc72f95f07438abd75ae3a9.zip |
Add function to get memory context stats for processes
This adds a function for retrieving memory context statistics
and information from backends as well as auxiliary processes.
The intended usecase is cluster debugging when under memory
pressure or unanticipated memory usage characteristics.
When calling the function it sends a signal to the specified
process to submit statistics regarding its memory contexts
into dynamic shared memory. Each memory context is returned
in detail, followed by a cumulative total in case the number
of contexts exceed the max allocated amount of shared memory.
Each process is limited to use at most 1Mb memory for this.
A summary can also be explicitly requested by the user, this
will return the TopMemoryContext and a cumulative total of
all lower contexts.
In order to not block on busy processes the caller specifies
the number of seconds during which to retry before timing out.
In the case where no statistics are published within the set
timeout, the last known statistics are returned, or NULL if
no previously published statistics exist. This allows dash-
board type queries to continually publish even if the target
process is temporarily congested. Context records contain a
timestamp to indicate when they were submitted.
Author: Rahila Syed <rahilasyed90@gmail.com>
Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
Reviewed-by: Andres Freund <andres@anarazel.de>
Reviewed-by: Tomas Vondra <tomas@vondra.me>
Reviewed-by: Atsushi Torikoshi <torikoshia@oss.nttdata.com>
Reviewed-by: Fujii Masao <masao.fujii@oss.nttdata.com>
Reviewed-by: Alexander Korotkov <aekorotkov@gmail.com>
Discussion: https://postgr.es/m/CAH2L28v8mc9HDt8QoSJ8TRmKau_8FM_HKS41NeO9-6ZAkuZKXw@mail.gmail.com
Diffstat (limited to 'src/include/utils/memutils.h')
-rw-r--r-- | src/include/utils/memutils.h | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/src/include/utils/memutils.h b/src/include/utils/memutils.h index 8abc26abce2..d328270fafc 100644 --- a/src/include/utils/memutils.h +++ b/src/include/utils/memutils.h @@ -18,6 +18,9 @@ #define MEMUTILS_H #include "nodes/memnodes.h" +#include "storage/condition_variable.h" +#include "storage/lmgr.h" +#include "utils/dsa.h" /* @@ -48,6 +51,23 @@ #define AllocHugeSizeIsValid(size) ((Size) (size) <= MaxAllocHugeSize) +/* + * Memory Context reporting size limits. + */ + +/* Max length of context name and ident */ +#define MEMORY_CONTEXT_IDENT_SHMEM_SIZE 64 +/* Maximum size (in bytes) of DSA area per process */ +#define MEMORY_CONTEXT_REPORT_MAX_PER_BACKEND ((size_t) (1 * 1024 * 1024)) + +/* + * Maximum size per context. Actual size may be lower as this assumes the worst + * case of deepest path and longest identifiers (name and ident, thus the + * multiplication by 2). The path depth is limited to 100 like for memory + * context logging. + */ +#define MAX_MEMORY_CONTEXT_STATS_SIZE (sizeof(MemoryStatsEntry) + \ + (100 * sizeof(int)) + (2 * MEMORY_CONTEXT_IDENT_SHMEM_SIZE)) /* * Standard top-level memory contexts. @@ -319,4 +339,66 @@ pg_memory_is_all_zeros(const void *ptr, size_t len) return true; } +/* Dynamic shared memory state for statistics per context */ +typedef struct MemoryStatsEntry +{ + dsa_pointer name; + dsa_pointer ident; + dsa_pointer path; + NodeTag type; + int path_length; + int levels; + int64 totalspace; + int64 nblocks; + int64 freespace; + int64 freechunks; + int num_agg_stats; +} MemoryStatsEntry; + +/* + * Static shared memory state representing the DSA area created for memory + * context statistics reporting. A single DSA area is created and used by all + * the processes, each having its specific DSA allocations for sharing memory + * statistics, tracked by per backend static shared memory state. + */ +typedef struct MemoryStatsCtl +{ + dsa_handle memstats_dsa_handle; + LWLock lw_lock; +} MemoryStatsCtl; + +/* + * Per backend static shared memory state for memory context statistics + * reporting. + */ +typedef struct MemoryStatsBackendState +{ + ConditionVariable memcxt_cv; + LWLock lw_lock; + int proc_id; + int total_stats; + bool summary; + dsa_pointer memstats_dsa_pointer; + TimestampTz stats_timestamp; +} MemoryStatsBackendState; + + +/* + * Used for storage of transient identifiers for pg_get_backend_memory_contexts + */ +typedef struct MemoryStatsContextId +{ + MemoryContext context; + int context_id; +} MemoryStatsContextId; + +extern PGDLLIMPORT MemoryStatsBackendState *memCxtState; +extern PGDLLIMPORT MemoryStatsCtl *memCxtArea; +extern void ProcessGetMemoryContextInterrupt(void); +extern const char *ContextTypeToString(NodeTag type); +extern void HandleGetMemoryContextInterrupt(void); +extern Size MemoryContextReportingShmemSize(void); +extern void MemoryContextReportingShmemInit(void); +extern void AtProcExit_memstats_cleanup(int code, Datum arg); +extern dsa_area *area; #endif /* MEMUTILS_H */ |