In [1] Andres mentioned that there's no way to determine the memory context type in pg_backend_memory_contexts. This is a bit annoying as I'd like to add a test to exercise BumpStats().
Having the context type in the test's expected output helps ensure we are exercising BumpStats() and any future changes to the choice of context type in tuplesort.c gets flagged up by the test breaking. It's probably too late for PG17, but I'll leave this here for the July CF. David [1] https://www.postgresql.org/message-id/20240415225749.xg7uq2hwuq2qm...@awork3.anarazel.de
From 0a58697a4b88bc3ac80f09ed78b56ebe903a2aae Mon Sep 17 00:00:00 2001 From: David Rowley <dgrow...@gmail.com> Date: Tue, 16 Apr 2024 13:05:34 +1200 Subject: [PATCH v1] Add context type field to pg_backend_memory_contexts --- doc/src/sgml/system-views.sgml | 9 +++++ src/backend/utils/adt/mcxtfuncs.c | 50 ++++++++++++++++++-------- src/include/catalog/pg_proc.dat | 6 ++-- src/test/regress/expected/rules.out | 5 +-- src/test/regress/expected/sysviews.out | 8 ++--- src/test/regress/sql/sysviews.sql | 2 +- 6 files changed, 56 insertions(+), 24 deletions(-) diff --git a/doc/src/sgml/system-views.sgml b/doc/src/sgml/system-views.sgml index 7ed617170f..18ae5b9138 100644 --- a/doc/src/sgml/system-views.sgml +++ b/doc/src/sgml/system-views.sgml @@ -463,6 +463,15 @@ </thead> <tbody> + <row> + <entry role="catalog_table_entry"><para role="column_definition"> + <structfield>type</structfield> <type>text</type> + </para> + <para> + Type of the memory context + </para></entry> + </row> + <row> <entry role="catalog_table_entry"><para role="column_definition"> <structfield>name</structfield> <type>text</type> diff --git a/src/backend/utils/adt/mcxtfuncs.c b/src/backend/utils/adt/mcxtfuncs.c index 4d4a70915b..fe52d57fd4 100644 --- a/src/backend/utils/adt/mcxtfuncs.c +++ b/src/backend/utils/adt/mcxtfuncs.c @@ -36,12 +36,13 @@ PutMemoryContextsStatsTupleStore(Tuplestorestate *tupstore, TupleDesc tupdesc, MemoryContext context, const char *parent, int level) { -#define PG_GET_BACKEND_MEMORY_CONTEXTS_COLS 9 +#define PG_GET_BACKEND_MEMORY_CONTEXTS_COLS 10 Datum values[PG_GET_BACKEND_MEMORY_CONTEXTS_COLS]; bool nulls[PG_GET_BACKEND_MEMORY_CONTEXTS_COLS]; MemoryContextCounters stat; MemoryContext child; + const char *type; const char *name; const char *ident; @@ -67,10 +68,31 @@ PutMemoryContextsStatsTupleStore(Tuplestorestate *tupstore, memset(values, 0, sizeof(values)); memset(nulls, 0, sizeof(nulls)); + switch (context->type) + { + case T_AllocSetContext: + type = "AllocSet"; + break; + case T_GenerationContext: + type = "Generation"; + break; + case T_SlabContext: + type = "Slab"; + break; + case T_BumpContext: + type = "Bump"; + break; + default: + type = "???"; + break; + } + + values[0] = CStringGetTextDatum(type); + if (name) - values[0] = CStringGetTextDatum(name); + values[1] = CStringGetTextDatum(name); else - nulls[0] = true; + nulls[1] = true; if (ident) { @@ -86,22 +108,22 @@ PutMemoryContextsStatsTupleStore(Tuplestorestate *tupstore, memcpy(clipped_ident, ident, idlen); clipped_ident[idlen] = '\0'; - values[1] = CStringGetTextDatum(clipped_ident); + values[2] = CStringGetTextDatum(clipped_ident); } else - nulls[1] = true; + nulls[2] = true; if (parent) - values[2] = CStringGetTextDatum(parent); + values[3] = CStringGetTextDatum(parent); else - nulls[2] = true; - - values[3] = Int32GetDatum(level); - values[4] = Int64GetDatum(stat.totalspace); - values[5] = Int64GetDatum(stat.nblocks); - values[6] = Int64GetDatum(stat.freespace); - values[7] = Int64GetDatum(stat.freechunks); - values[8] = Int64GetDatum(stat.totalspace - stat.freespace); + nulls[3] = true; + + values[4] = Int32GetDatum(level); + values[5] = Int64GetDatum(stat.totalspace); + values[6] = Int64GetDatum(stat.nblocks); + values[7] = Int64GetDatum(stat.freespace); + values[8] = Int64GetDatum(stat.freechunks); + values[9] = Int64GetDatum(stat.totalspace - stat.freespace); tuplestore_putvalues(tupstore, tupdesc, values, nulls); for (child = context->firstchild; child != NULL; child = child->nextchild) diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 134e3b22fd..adda675887 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -8277,9 +8277,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,text,int4,int8,int8,int8,int8,int8}', + proargmodes => '{o,o,o,o,o,o,o,o,o,o}', + proargnames => '{type, name, ident, parent, level, total_bytes, total_nblocks, free_bytes, free_chunks, used_bytes}', 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 f4a0f36377..a8ac58201d 100644 --- a/src/test/regress/expected/rules.out +++ b/src/test/regress/expected/rules.out @@ -1303,7 +1303,8 @@ pg_available_extensions| SELECT e.name, e.comment FROM (pg_available_extensions() e(name, default_version, comment) LEFT JOIN pg_extension x ON ((e.name = x.extname))); -pg_backend_memory_contexts| SELECT name, +pg_backend_memory_contexts| SELECT type, + name, ident, parent, level, @@ -1312,7 +1313,7 @@ pg_backend_memory_contexts| SELECT name, 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); + FROM pg_get_backend_memory_contexts() pg_get_backend_memory_contexts(type, name, ident, parent, level, total_bytes, total_nblocks, free_bytes, free_chunks, used_bytes); pg_config| SELECT name, setting FROM pg_config() pg_config(name, setting); diff --git a/src/test/regress/expected/sysviews.out b/src/test/regress/expected/sysviews.out index 9be7aca2b8..85585facdc 100644 --- a/src/test/regress/expected/sysviews.out +++ b/src/test/regress/expected/sysviews.out @@ -21,11 +21,11 @@ select count(*) >= 0 as ok from pg_available_extensions; -- The entire output of pg_backend_memory_contexts is not stable, -- we test only the existence and basic condition of TopMemoryContext. -select name, ident, parent, level, total_bytes >= free_bytes +select type, name, ident, parent, level, total_bytes >= free_bytes from pg_backend_memory_contexts where level = 0; - name | ident | parent | level | ?column? -------------------+-------+--------+-------+---------- - TopMemoryContext | | | 0 | t + type | name | ident | parent | level | ?column? +----------+------------------+-------+--------+-------+---------- + AllocSet | TopMemoryContext | | | 0 | t (1 row) -- At introduction, pg_config had 23 entries; it may grow diff --git a/src/test/regress/sql/sysviews.sql b/src/test/regress/sql/sysviews.sql index 6b4e24601d..eb4bbf01b2 100644 --- a/src/test/regress/sql/sysviews.sql +++ b/src/test/regress/sql/sysviews.sql @@ -14,7 +14,7 @@ select count(*) >= 0 as ok from pg_available_extensions; -- The entire output of pg_backend_memory_contexts is not stable, -- we test only the existence and basic condition of TopMemoryContext. -select name, ident, parent, level, total_bytes >= free_bytes +select type, name, ident, parent, level, total_bytes >= free_bytes from pg_backend_memory_contexts where level = 0; -- At introduction, pg_config had 23 entries; it may grow -- 2.40.1.windows.1