1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-18 17:42:25 +03:00

Introduce pg_dsm_registry_allocations view.

This commit adds a new system view that provides information about
entries in the dynamic shared memory (DSM) registry.  Specifically,
it returns the name, type, and size of each entry.  Note that since
we cannot discover the size of dynamic shared memory areas (DSAs)
and hash tables backed by DSAs (dshashes) without first attaching
to them, the size column is left as NULL for those.

Bumps catversion.

Author: Florents Tselai <florents.tselai@gmail.com>
Reviewed-by: Sungwoo Chang <swchangdev@gmail.com>
Discussion: https://postgr.es/m/4D445D3E-81C5-4135-95BB-D414204A0AB4%40gmail.com
This commit is contained in:
Nathan Bossart
2025-07-09 09:17:56 -05:00
parent f5a987c0e5
commit 167ed8082f
10 changed files with 187 additions and 3 deletions

View File

@ -81,6 +81,11 @@
<entry>open cursors</entry>
</row>
<row>
<entry><link linkend="view-pg-dsm-registry-allocations"><structname>pg_dsm_registry_allocations</structname></link></entry>
<entry>shared memory allocations tracked in the DSM registry</entry>
</row>
<row>
<entry><link linkend="view-pg-file-settings"><structname>pg_file_settings</structname></link></entry>
<entry>summary of configuration file contents</entry>
@ -1086,6 +1091,75 @@ AND c1.path[c2.level] = c2.path[c2.level];
</sect1>
<sect1 id="view-pg-dsm-registry-allocations">
<title><structname>pg_dsm_registry_allocations</structname></title>
<indexterm zone="view-pg-dsm-registry-allocations">
<primary>pg_dsm_registry_allocations</primary>
</indexterm>
<para>
The <structname>pg_dsm_registry_allocations</structname> view shows shared
memory allocations tracked in the dynamic shared memory (DSM) registry.
This includes memory allocated by extensions using the mechanisms detailed
in <xref linkend="xfunc-shared-addin-after-startup" />.
</para>
<table>
<title><structname>pg_dsm_registry_allocations</structname> Columns</title>
<tgroup cols="1">
<thead>
<row>
<entry role="catalog_table_entry"><para role="column_definition">
Column Type
</para>
<para>
Description
</para></entry>
</row>
</thead>
<tbody>
<row>
<entry role="catalog_table_entry"><para role="column_definition">
<structfield>name</structfield> <type>text</type>
</para>
<para>
The name of the allocation in the DSM registry.
</para></entry>
</row>
<row>
<entry role="catalog_table_entry"><para role="column_definition">
<structfield>type</structfield> <type>text</type>
</para>
<para>
The type of allocation. Possible values are <literal>segment</literal>,
<literal>area</literal>, and <literal>hash</literal>, which correspond
to dynamic shared memory segments, areas, and hash tables, respectively.
</para></entry>
</row>
<row>
<entry role="catalog_table_entry"><para role="column_definition">
<structfield>size</structfield> <type>int8</type>
</para>
<para>
Size of the allocation in bytes. NULL for entries of type
<literal>area</literal> and <literal>hash</literal>.
</para></entry>
</row>
</tbody>
</tgroup>
</table>
<para>
By default, the <structname>pg_dsm_registry_allocations</structname> view
can be read only by superusers or roles with privileges of the
<literal>pg_read_all_stats</literal> role.
</para>
</sect1>
<sect1 id="view-pg-file-settings">
<title><structname>pg_file_settings</structname></title>

View File

@ -666,6 +666,14 @@ GRANT SELECT ON pg_shmem_allocations_numa TO pg_read_all_stats;
REVOKE EXECUTE ON FUNCTION pg_get_shmem_allocations_numa() FROM PUBLIC;
GRANT EXECUTE ON FUNCTION pg_get_shmem_allocations_numa() TO pg_read_all_stats;
CREATE VIEW pg_dsm_registry_allocations AS
SELECT * FROM pg_get_dsm_registry_allocations();
REVOKE ALL ON pg_dsm_registry_allocations FROM PUBLIC;
GRANT SELECT ON pg_dsm_registry_allocations TO pg_read_all_stats;
REVOKE EXECUTE ON FUNCTION pg_get_dsm_registry_allocations() FROM PUBLIC;
GRANT EXECUTE ON FUNCTION pg_get_dsm_registry_allocations() TO pg_read_all_stats;
CREATE VIEW pg_backend_memory_contexts AS
SELECT * FROM pg_get_backend_memory_contexts();

View File

@ -40,10 +40,12 @@
#include "postgres.h"
#include "funcapi.h"
#include "lib/dshash.h"
#include "storage/dsm_registry.h"
#include "storage/lwlock.h"
#include "storage/shmem.h"
#include "utils/builtins.h"
#include "utils/memutils.h"
#define DSMR_NAME_LEN 128
@ -88,6 +90,13 @@ typedef enum DSMREntryType
DSMR_ENTRY_TYPE_DSH,
} DSMREntryType;
static const char *const DSMREntryTypeNames[] =
{
[DSMR_ENTRY_TYPE_DSM] = "segment",
[DSMR_ENTRY_TYPE_DSA] = "area",
[DSMR_ENTRY_TYPE_DSH] = "hash",
};
typedef struct DSMRegistryEntry
{
char name[DSMR_NAME_LEN];
@ -435,3 +444,43 @@ GetNamedDSHash(const char *name, const dshash_parameters *params, bool *found)
return ret;
}
Datum
pg_get_dsm_registry_allocations(PG_FUNCTION_ARGS)
{
ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
DSMRegistryEntry *entry;
MemoryContext oldcontext;
dshash_seq_status status;
InitMaterializedSRF(fcinfo, MAT_SRF_USE_EXPECTED_DESC);
/* Be sure any local memory allocated by DSM/DSA routines is persistent. */
oldcontext = MemoryContextSwitchTo(TopMemoryContext);
init_dsm_registry();
MemoryContextSwitchTo(oldcontext);
dshash_seq_init(&status, dsm_registry_table, false);
while ((entry = dshash_seq_next(&status)) != NULL)
{
Datum vals[3];
bool nulls[3] = {0};
vals[0] = CStringGetTextDatum(entry->name);
vals[1] = CStringGetTextDatum(DSMREntryTypeNames[entry->type]);
/*
* Since we can't know the size of DSA/dshash entries without first
* attaching to them, return NULL for those.
*/
if (entry->type == DSMR_ENTRY_TYPE_DSM)
vals[2] = Int64GetDatum(entry->data.dsm.size);
else
nulls[2] = true;
tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, vals, nulls);
}
dshash_seq_term(&status);
return (Datum) 0;
}

View File

@ -57,6 +57,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 202506301
#define CATALOG_VERSION_NO 202507091
#endif

View File

@ -8572,6 +8572,14 @@
proargnames => '{name,numa_node,size}',
prosrc => 'pg_get_shmem_allocations_numa' },
{ oid => '9314',
descr => 'shared memory allocations tracked in the DSM registry',
proname => 'pg_get_dsm_registry_allocations', prorows => '50',
proretset => 't', provolatile => 'v', prorettype => 'record',
proargtypes => '', proallargtypes => '{text,text,int8}',
proargmodes => '{o,o,o}', proargnames => '{name,type,size}',
prosrc => 'pg_get_dsm_registry_allocations' },
# memory context of local backend
{ oid => '2282',
descr => 'information about all memory contexts of local backend',

View File

@ -1,3 +1,10 @@
SELECT name, type, size IS DISTINCT FROM 0 AS size
FROM pg_dsm_registry_allocations
WHERE name like 'test_dsm_registry%' ORDER BY name;
name | type | size
------+------+------
(0 rows)
CREATE EXTENSION test_dsm_registry;
SELECT set_val_in_shmem(1236);
set_val_in_shmem
@ -24,3 +31,14 @@ SELECT get_val_in_hash('test');
1414
(1 row)
\c
SELECT name, type, size IS DISTINCT FROM 0 AS size
FROM pg_dsm_registry_allocations
WHERE name like 'test_dsm_registry%' ORDER BY name;
name | type | size
------------------------+---------+------
test_dsm_registry_dsa | area | t
test_dsm_registry_dsm | segment | t
test_dsm_registry_hash | hash | t
(3 rows)

View File

@ -1,6 +1,13 @@
SELECT name, type, size IS DISTINCT FROM 0 AS size
FROM pg_dsm_registry_allocations
WHERE name like 'test_dsm_registry%' ORDER BY name;
CREATE EXTENSION test_dsm_registry;
SELECT set_val_in_shmem(1236);
SELECT set_val_in_hash('test', '1414');
\c
SELECT get_val_in_shmem();
SELECT get_val_in_hash('test');
\c
SELECT name, type, size IS DISTINCT FROM 0 AS size
FROM pg_dsm_registry_allocations
WHERE name like 'test_dsm_registry%' ORDER BY name;

View File

@ -3220,7 +3220,8 @@ REVOKE MAINTAIN ON lock_table FROM regress_locktable_user;
DROP TABLE lock_table;
DROP USER regress_locktable_user;
-- test to check privileges of system views pg_shmem_allocations,
-- pg_shmem_allocations_numa and pg_backend_memory_contexts.
-- pg_shmem_allocations_numa, pg_dsm_registry_allocations, and
-- pg_backend_memory_contexts.
-- switch to superuser
\c -
CREATE ROLE regress_readallstats;
@ -3248,6 +3249,12 @@ SELECT has_table_privilege('regress_readallstats','pg_shmem_allocations_numa','S
f
(1 row)
SELECT has_table_privilege('regress_readallstats','pg_dsm_registry_allocations','SELECT'); -- no
has_table_privilege
---------------------
f
(1 row)
GRANT pg_read_all_stats TO regress_readallstats;
SELECT has_table_privilege('regress_readallstats','pg_aios','SELECT'); -- yes
has_table_privilege
@ -3273,6 +3280,12 @@ SELECT has_table_privilege('regress_readallstats','pg_shmem_allocations_numa','S
t
(1 row)
SELECT has_table_privilege('regress_readallstats','pg_dsm_registry_allocations','SELECT'); -- yes
has_table_privilege
---------------------
t
(1 row)
-- run query to ensure that functions within views can be executed
SET ROLE regress_readallstats;
SELECT COUNT(*) >= 0 AS ok FROM pg_aios;

View File

@ -1340,6 +1340,10 @@ pg_cursors| SELECT name,
is_scrollable,
creation_time
FROM pg_cursor() c(name, statement, is_holdable, is_binary, is_scrollable, creation_time);
pg_dsm_registry_allocations| SELECT name,
type,
size
FROM pg_get_dsm_registry_allocations() pg_get_dsm_registry_allocations(name, type, size);
pg_file_settings| SELECT sourcefile,
sourceline,
seqno,

View File

@ -1948,7 +1948,8 @@ DROP TABLE lock_table;
DROP USER regress_locktable_user;
-- test to check privileges of system views pg_shmem_allocations,
-- pg_shmem_allocations_numa and pg_backend_memory_contexts.
-- pg_shmem_allocations_numa, pg_dsm_registry_allocations, and
-- pg_backend_memory_contexts.
-- switch to superuser
\c -
@ -1959,6 +1960,7 @@ SELECT has_table_privilege('regress_readallstats','pg_aios','SELECT'); -- no
SELECT has_table_privilege('regress_readallstats','pg_backend_memory_contexts','SELECT'); -- no
SELECT has_table_privilege('regress_readallstats','pg_shmem_allocations','SELECT'); -- no
SELECT has_table_privilege('regress_readallstats','pg_shmem_allocations_numa','SELECT'); -- no
SELECT has_table_privilege('regress_readallstats','pg_dsm_registry_allocations','SELECT'); -- no
GRANT pg_read_all_stats TO regress_readallstats;
@ -1966,6 +1968,7 @@ SELECT has_table_privilege('regress_readallstats','pg_aios','SELECT'); -- yes
SELECT has_table_privilege('regress_readallstats','pg_backend_memory_contexts','SELECT'); -- yes
SELECT has_table_privilege('regress_readallstats','pg_shmem_allocations','SELECT'); -- yes
SELECT has_table_privilege('regress_readallstats','pg_shmem_allocations_numa','SELECT'); -- yes
SELECT has_table_privilege('regress_readallstats','pg_dsm_registry_allocations','SELECT'); -- yes
-- run query to ensure that functions within views can be executed
SET ROLE regress_readallstats;