v2-0001-Adding-id-parent_id-into-pg_backend_memory_contex.patch
application/octet-stream
Filename: v2-0001-Adding-id-parent_id-into-pg_backend_memory_contex.patch
Type: application/octet-stream
Part: 0
Patch
Format: format-patch
Series: patch v2-0001
Subject: Adding id/parent_id into pg_backend_memory_contexts
| File | + | − |
|---|---|---|
| doc/src/sgml/system-views.sgml | 27 | 0 |
| src/backend/utils/adt/mcxtfuncs.c | 54 | 5 |
| src/include/catalog/pg_proc.dat | 3 | 3 |
| src/test/regress/expected/rules.out | 5 | 2 |
From e9134ad5465d0dae626cf658def2ca58648d64c2 Mon Sep 17 00:00:00 2001
From: Melih Mutlu <m.melihmutlu@gmail.com>
Date: Tue, 13 Jun 2023 15:00:05 +0300
Subject: [PATCH v2] Adding id/parent_id into pg_backend_memory_contexts
Added three new fields into the tuples returned by
pg_get_backend_memory_contexts() to specify the parent/child relation
between memory contexts and the path from root to current context.
Context names cannot be relied on since they're not unique. Therefore,
unique id and parent_id are needed for each context. Those new id's are
assigned during pg_get_backend_memory_contexts() call and not stored
anywhere. So they may change in each pg_get_backend_memory_contexts()
call and shouldn't be used across differenct
pg_get_backend_memory_contexts() calls.
Context id's are start from 0 which is assigned to TopMemoryContext.
---
doc/src/sgml/system-views.sgml | 27 +++++++++++++
src/backend/utils/adt/mcxtfuncs.c | 59 ++++++++++++++++++++++++++---
src/include/catalog/pg_proc.dat | 6 +--
src/test/regress/expected/rules.out | 7 +++-
4 files changed, 89 insertions(+), 10 deletions(-)
diff --git a/doc/src/sgml/system-views.sgml b/doc/src/sgml/system-views.sgml
index 57b228076e..7811130cfb 100644
--- a/doc/src/sgml/system-views.sgml
+++ b/doc/src/sgml/system-views.sgml
@@ -538,6 +538,33 @@
Used space in bytes
</para></entry>
</row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>context_id</structfield> <type>int4</type>
+ </para>
+ <para>
+ Current context id
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>parent_id</structfield> <type>int4</type>
+ </para>
+ <para>
+ Parent context id
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>path</structfield> <type>int4</type>
+ </para>
+ <para>
+ Path to reach the current context from TopMemoryContext
+ </para></entry>
+ </row>
</tbody>
</tgroup>
</table>
diff --git a/src/backend/utils/adt/mcxtfuncs.c b/src/backend/utils/adt/mcxtfuncs.c
index 92ca5b2f72..81cb35dd47 100644
--- a/src/backend/utils/adt/mcxtfuncs.c
+++ b/src/backend/utils/adt/mcxtfuncs.c
@@ -20,6 +20,7 @@
#include "mb/pg_wchar.h"
#include "storage/proc.h"
#include "storage/procarray.h"
+#include "utils/array.h"
#include "utils/builtins.h"
/* ----------
@@ -28,6 +29,8 @@
*/
#define MEMORY_CONTEXT_IDENT_DISPLAY_SIZE 1024
+static Datum convert_path_to_datum(List *path);
+
/*
* PutMemoryContextsStatsTupleStore
* One recursion level for pg_get_backend_memory_contexts.
@@ -35,9 +38,10 @@
static void
PutMemoryContextsStatsTupleStore(Tuplestorestate *tupstore,
TupleDesc tupdesc, MemoryContext context,
- const char *parent, int level)
+ const char *parent, int level, int *context_id,
+ int parent_id, List *path)
{
-#define PG_GET_BACKEND_MEMORY_CONTEXTS_COLS 9
+#define PG_GET_BACKEND_MEMORY_CONTEXTS_COLS 12
Datum values[PG_GET_BACKEND_MEMORY_CONTEXTS_COLS];
bool nulls[PG_GET_BACKEND_MEMORY_CONTEXTS_COLS];
@@ -45,6 +49,7 @@ PutMemoryContextsStatsTupleStore(Tuplestorestate *tupstore,
MemoryContext child;
const char *name;
const char *ident;
+ int current_context_id = (*context_id)++;
Assert(MemoryContextIsValid(context));
@@ -103,13 +108,29 @@ PutMemoryContextsStatsTupleStore(Tuplestorestate *tupstore,
values[6] = Int64GetDatum(stat.freespace);
values[7] = Int64GetDatum(stat.freechunks);
values[8] = Int64GetDatum(stat.totalspace - stat.freespace);
+ values[9] = Int32GetDatum(current_context_id);
+
+ if(parent_id < 0)
+ /* TopMemoryContext has no parent context */
+ nulls[10] = true;
+ else
+ values[10] = Int32GetDatum(parent_id);
+
+ if (path == NIL)
+ nulls[11] = true;
+ else
+ values[11] = convert_path_to_datum(path);
+
tuplestore_putvalues(tupstore, tupdesc, values, nulls);
+ path = lappend_int(path, current_context_id);
for (child = context->firstchild; child != NULL; child = child->nextchild)
{
- PutMemoryContextsStatsTupleStore(tupstore, tupdesc,
- child, name, level + 1);
+ PutMemoryContextsStatsTupleStore(tupstore, tupdesc, child, name,
+ level+1, context_id,
+ current_context_id, path);
}
+ path = list_delete_last(path);
}
/*
@@ -120,10 +141,15 @@ Datum
pg_get_backend_memory_contexts(PG_FUNCTION_ARGS)
{
ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
+ int context_id = 0;
+ List *path = NIL;
+
+ elog(LOG, "pg_get_backend_memory_contexts called");
InitMaterializedSRF(fcinfo, 0);
PutMemoryContextsStatsTupleStore(rsinfo->setResult, rsinfo->setDesc,
- TopMemoryContext, NULL, 0);
+ TopMemoryContext, NULL, 0, &context_id,
+ -1, path);
return (Datum) 0;
}
@@ -193,3 +219,26 @@ pg_log_backend_memory_contexts(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(true);
}
+
+/*
+ * Convert a list of context ids to a int[] Datum
+ */
+static Datum
+convert_path_to_datum(List *path)
+{
+ Datum *datum_array;
+ int length;
+ ArrayType *result_array;
+ ListCell *lc;
+
+ length = list_length(path);
+ datum_array = (Datum *) palloc(length * sizeof(Datum));
+ length = 0;
+ foreach(lc, path)
+ {
+ datum_array[length++] = Int32GetDatum((int) lfirst_int(lc));
+ }
+ result_array = construct_array_builtin(datum_array, length, INT4OID);
+
+ return PointerGetDatum(result_array);
+}
\ No newline at end of file
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 6996073989..49514ad792 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -8212,9 +8212,9 @@
proname => 'pg_get_backend_memory_contexts', prorows => '100',
proretset => 't', provolatile => 'v', proparallel => 'r',
prorettype => 'record', proargtypes => '',
- proallargtypes => '{text,text,text,int4,int8,int8,int8,int8,int8}',
- proargmodes => '{o,o,o,o,o,o,o,o,o}',
- proargnames => '{name, ident, parent, level, total_bytes, total_nblocks, free_bytes, free_chunks, used_bytes}',
+ proallargtypes => '{text,text,text,int4,int8,int8,int8,int8,int8,int4,int4,_int4}',
+ proargmodes => '{o,o,o,o,o,o,o,o,o,o,o,o}',
+ proargnames => '{name, ident, parent, level, total_bytes, total_nblocks, free_bytes, free_chunks, used_bytes, id, parent_id, path}',
prosrc => 'pg_get_backend_memory_contexts' },
# logging memory contexts of the specified backend
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e07afcd4aa..c7112be09e 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1311,8 +1311,11 @@ pg_backend_memory_contexts| SELECT name,
total_nblocks,
free_bytes,
free_chunks,
- used_bytes
- FROM pg_get_backend_memory_contexts() pg_get_backend_memory_contexts(name, ident, parent, level, total_bytes, total_nblocks, free_bytes, free_chunks, used_bytes);
+ used_bytes,
+ id,
+ parent_id,
+ path
+ FROM pg_get_backend_memory_contexts() pg_get_backend_memory_contexts(name, ident, parent, level, total_bytes, total_nblocks, free_bytes, free_chunks, used_bytes, id, parent_id, path);
pg_config| SELECT name,
setting
FROM pg_config() pg_config(name, setting);
--
2.25.1