mirror of
https://github.com/postgres/postgres.git
synced 2025-11-26 23:43:30 +03:00
Commit 3e98c0bafb added pg_backend_memory_contexts view to display
the memory contexts of the backend process. However its target process
is limited to the backend that is accessing to the view. So this is
not so convenient when investigating the local memory bloat of other
backend process. To improve this situation, this commit adds
pg_log_backend_memory_contexts() function that requests to log
the memory contexts of the specified backend process.
This information can be also collected by calling
MemoryContextStats(TopMemoryContext) via a debugger. But
this technique cannot be used in some environments because no debugger
is available there. So, pg_log_backend_memory_contexts() allows us to
see the memory contexts of specified backend more easily.
Only superusers are allowed to request 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.
On receipt of the request, at the next CHECK_FOR_INTERRUPTS(),
the target backend logs its memory contexts at LOG_SERVER_ONLY level,
so that these memory contexts will appear in the server log but not
be sent to the client. It logs one message per memory context.
Because if it buffers all memory contexts into StringInfo to log them
as one message, which may require the buffer to be enlarged very much
and lead to OOM error since there can be a large number of memory
contexts in a backend.
When a backend process is consuming huge memory, logging all its
memory contexts might overrun available disk space. To prevent this,
now this patch limits the number of child contexts to log per parent
to 100. As with MemoryContextStats(), it supposes that practical cases
where the log gets long will typically be huge numbers of siblings
under the same parent context; while the additional debugging value
from seeing details about individual siblings beyond 100 will not be large.
There was another proposed patch to add the function to return
the memory contexts of specified backend as the result sets,
instead of logging them, in the discussion. However that patch is
not included in this commit because it had several issues to address.
Thanks to Tatsuhito Kasahara, Andres Freund, Tom Lane, Tomas Vondra,
Michael Paquier, Kyotaro Horiguchi and Zhihong Yu for the discussion.
Bump catalog version.
Author: Atsushi Torikoshi
Reviewed-by: Kyotaro Horiguchi, Zhihong Yu, Fujii Masao
Discussion: https://postgr.es/m/0271f440ac77f2a4180e0e56ebd944d1@oss.nttdata.com
111 lines
3.9 KiB
C
111 lines
3.9 KiB
C
/*-------------------------------------------------------------------------
|
|
*
|
|
* memnodes.h
|
|
* POSTGRES memory context node definitions.
|
|
*
|
|
*
|
|
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
|
*
|
|
* src/include/nodes/memnodes.h
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
#ifndef MEMNODES_H
|
|
#define MEMNODES_H
|
|
|
|
#include "nodes/nodes.h"
|
|
|
|
/*
|
|
* MemoryContextCounters
|
|
* Summarization state for MemoryContextStats collection.
|
|
*
|
|
* The set of counters in this struct is biased towards AllocSet; if we ever
|
|
* add any context types that are based on fundamentally different approaches,
|
|
* we might need more or different counters here. A possible API spec then
|
|
* would be to print only nonzero counters, but for now we just summarize in
|
|
* the format historically used by AllocSet.
|
|
*/
|
|
typedef struct MemoryContextCounters
|
|
{
|
|
Size nblocks; /* Total number of malloc blocks */
|
|
Size freechunks; /* Total number of free chunks */
|
|
Size totalspace; /* Total bytes requested from malloc */
|
|
Size freespace; /* The unused portion of totalspace */
|
|
} MemoryContextCounters;
|
|
|
|
/*
|
|
* MemoryContext
|
|
* A logical context in which memory allocations occur.
|
|
*
|
|
* MemoryContext itself is an abstract type that can have multiple
|
|
* implementations.
|
|
* The function pointers in MemoryContextMethods define one specific
|
|
* implementation of MemoryContext --- they are a virtual function table
|
|
* in C++ terms.
|
|
*
|
|
* Node types that are actual implementations of memory contexts must
|
|
* begin with the same fields as MemoryContextData.
|
|
*
|
|
* Note: for largely historical reasons, typedef MemoryContext is a pointer
|
|
* to the context struct rather than the struct type itself.
|
|
*/
|
|
|
|
typedef void (*MemoryStatsPrintFunc) (MemoryContext context, void *passthru,
|
|
const char *stats_string,
|
|
bool print_to_stderr);
|
|
|
|
typedef struct MemoryContextMethods
|
|
{
|
|
void *(*alloc) (MemoryContext context, Size size);
|
|
/* call this free_p in case someone #define's free() */
|
|
void (*free_p) (MemoryContext context, void *pointer);
|
|
void *(*realloc) (MemoryContext context, void *pointer, Size size);
|
|
void (*reset) (MemoryContext context);
|
|
void (*delete_context) (MemoryContext context);
|
|
Size (*get_chunk_space) (MemoryContext context, void *pointer);
|
|
bool (*is_empty) (MemoryContext context);
|
|
void (*stats) (MemoryContext context,
|
|
MemoryStatsPrintFunc printfunc, void *passthru,
|
|
MemoryContextCounters *totals,
|
|
bool print_to_stderr);
|
|
#ifdef MEMORY_CONTEXT_CHECKING
|
|
void (*check) (MemoryContext context);
|
|
#endif
|
|
} MemoryContextMethods;
|
|
|
|
|
|
typedef struct MemoryContextData
|
|
{
|
|
NodeTag type; /* identifies exact kind of context */
|
|
/* these two fields are placed here to minimize alignment wastage: */
|
|
bool isReset; /* T = no space alloced since last reset */
|
|
bool allowInCritSection; /* allow palloc in critical section */
|
|
Size mem_allocated; /* track memory allocated for this context */
|
|
const MemoryContextMethods *methods; /* virtual function table */
|
|
MemoryContext parent; /* NULL if no parent (toplevel context) */
|
|
MemoryContext firstchild; /* head of linked list of children */
|
|
MemoryContext prevchild; /* previous child of same parent */
|
|
MemoryContext nextchild; /* next child of same parent */
|
|
const char *name; /* context name (just for debugging) */
|
|
const char *ident; /* context ID if any (just for debugging) */
|
|
MemoryContextCallback *reset_cbs; /* list of reset/delete callbacks */
|
|
} MemoryContextData;
|
|
|
|
/* utils/palloc.h contains typedef struct MemoryContextData *MemoryContext */
|
|
|
|
|
|
/*
|
|
* MemoryContextIsValid
|
|
* True iff memory context is valid.
|
|
*
|
|
* Add new context types to the set accepted by this macro.
|
|
*/
|
|
#define MemoryContextIsValid(context) \
|
|
((context) != NULL && \
|
|
(IsA((context), AllocSetContext) || \
|
|
IsA((context), SlabContext) || \
|
|
IsA((context), GenerationContext)))
|
|
|
|
#endif /* MEMNODES_H */
|