v5-0001-Update-pg_dsm_registry_allocations-to-include-stu.patch
application/octet-stream
Filename: v5-0001-Update-pg_dsm_registry_allocations-to-include-stu.patch
Type: application/octet-stream
Part: 0
From 56deeba7514f9e3e8d91c9d0e5f56d206f1ec663 Mon Sep 17 00:00:00 2001
From: Florents Tselai <florents.tselai@gmail.com>
Date: Tue, 8 Jul 2025 14:06:57 +0300
Subject: [PATCH v5] Update pg_dsm_registry_allocations to include stuff added
in fe07100
---
doc/src/sgml/system-views.sgml | 84 +++++++++++++++++++
src/backend/catalog/system_views.sql | 8 ++
src/backend/storage/ipc/dsm_registry.c | 66 +++++++++++++++
src/include/catalog/pg_proc.dat | 6 ++
.../expected/test_dsm_registry.out | 9 ++
.../sql/test_dsm_registry.sql | 2 +
src/test/regress/expected/rules.out | 4 +
7 files changed, 179 insertions(+)
diff --git a/doc/src/sgml/system-views.sgml b/doc/src/sgml/system-views.sgml
index e1ac544ee40..c61c6f6b2a7 100644
--- a/doc/src/sgml/system-views.sgml
+++ b/doc/src/sgml/system-views.sgml
@@ -186,6 +186,11 @@
<entry>NUMA node mappings for shared memory allocations</entry>
</row>
+ <row>
+ <entry><link linkend="view-pg-dsm-registry-allocations"><structname>pg_dsm_registry_allocations</structname></link></entry>
+ <entry>DSM segment allocations registered via the DSM registry</entry>
+ </row>
+
<row>
<entry><link linkend="view-pg-stats"><structname>pg_stats</structname></link></entry>
<entry>planner statistics</entry>
@@ -4143,6 +4148,85 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
</para>
</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 current
+ allocations registered in the dynamic shared memory (DSM) registry. This
+ includes all entries that have been registered and tracked by
+ <productname>PostgreSQL</productname> during the server's operation. Entries
+ may represent a raw dynamic shared memory (DSM) segment, a dynamic shared
+ memory area (DSA), or a shared hash table (dshash) built on top of a DSA.
+ </para>
+
+ <para>
+ This view is useful for monitoring DSM usage by extensions or internal
+ components using dynamic shared memory segments.
+ </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 as registered 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>dsm</literal> for a
+ raw dynamic shared memory segment, <literal>dsa</literal> for a dynamic
+ shared memory area, and <literal>dsh</literal> for a dynamic shared hash table.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>size</structfield> <type>int8</type>
+ </para>
+ <para>
+ The size of the allocation in bytes. For entries of type <literal>dsm</literal>,
+ this reflects the actual size of the allocated DSM segment. For <literal>dsa</literal>
+ and <literal>dsh</literal> entries, the size is reported as <literal>NULL</literal>
+ because the server does not attach to these areas in order to retrieve their size.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ By default, access to the <structname>pg_dsm_registry_allocations</structname>
+ view is restricted to superusers or roles granted the
+ <literal>pg_read_all_stats</literal> role due to the sensitive nature
+ of dynamic shared memory usage information.
+ </para>
+ </sect1>
+
<sect1 id="view-pg-stats">
<title><structname>pg_stats</structname></title>
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index e5dbbe61b81..e637f080a37 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -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();
diff --git a/src/backend/storage/ipc/dsm_registry.c b/src/backend/storage/ipc/dsm_registry.c
index 828c2ff0c7f..1934e086b0a 100644
--- a/src/backend/storage/ipc/dsm_registry.c
+++ b/src/backend/storage/ipc/dsm_registry.c
@@ -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
@@ -435,3 +437,67 @@ 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;
+ dshash_seq_status status;
+
+ InitMaterializedSRF(fcinfo, MAT_SRF_USE_EXPECTED_DESC);
+
+ /* Ensure DSM registry initialized */
+ init_dsm_registry();
+
+ /* Use non-exclusive access to avoid blocking other backends */
+ dshash_seq_init(&status, dsm_registry_table, false);
+
+ while ((entry = dshash_seq_next(&status)) != NULL)
+ {
+ /* name, type, size */
+ Datum values[3];
+ bool nulls[3] = {false, false, false};
+
+ /* 0: name */
+ values[0] = CStringGetTextDatum(entry->name);
+
+ /* 1: type */
+ switch (entry->type) {
+ case DSMR_ENTRY_TYPE_DSM:
+ values[1] = CStringGetTextDatum("dsm");
+ break;
+ case DSMR_ENTRY_TYPE_DSA:
+ values[1] = CStringGetTextDatum("dsa");
+ break;
+ case DSMR_ENTRY_TYPE_DSH:
+ values[1] = CStringGetTextDatum("dsh");
+ break;
+ default:
+ values[1] = CStringGetTextDatum("unknown");
+ break;
+ }
+
+ /* 2: size */
+ switch (entry->type)
+ {
+ case DSMR_ENTRY_TYPE_DSM:
+ values[2] = Int64GetDatum(entry->data.dsm.size);
+ break;
+
+ /* in case of dsa or dsh we return NULL */
+ case DSMR_ENTRY_TYPE_DSA:
+ case DSMR_ENTRY_TYPE_DSH:
+ default:
+ nulls[2] = true;
+ break;
+ }
+
+ tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc,
+ values, nulls);
+ }
+
+ dshash_seq_term(&status);
+
+ return (Datum) 0;
+}
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index d4650947c63..2f5df3affae 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -8559,6 +8559,12 @@
proallargtypes => '{text,int8,int8,int8}', proargmodes => '{o,o,o,o}',
proargnames => '{name,off,size,allocated_size}',
prosrc => 'pg_get_shmem_allocations' },
+{ oid => '6062', descr => 'dsm registry allocations',
+ 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' },
{ oid => '4099', descr => 'Is NUMA support available?',
proname => 'pg_numa_available', provolatile => 's', prorettype => 'bool',
diff --git a/src/test/modules/test_dsm_registry/expected/test_dsm_registry.out b/src/test/modules/test_dsm_registry/expected/test_dsm_registry.out
index 8ded82e59d6..90f0a888a16 100644
--- a/src/test/modules/test_dsm_registry/expected/test_dsm_registry.out
+++ b/src/test/modules/test_dsm_registry/expected/test_dsm_registry.out
@@ -24,3 +24,12 @@ SELECT get_val_in_hash('test');
1414
(1 row)
+\c
+SELECT name, type, size > 0 OR size ISNULL as size FROM pg_dsm_registry_allocations WHERE name like 'test_dsm_registry%';
+ name | type | size
+------------------------+------+------
+ test_dsm_registry_dsa | dsa | t
+ test_dsm_registry_hash | dsh | t
+ test_dsm_registry_dsm | dsm | t
+(3 rows)
+
diff --git a/src/test/modules/test_dsm_registry/sql/test_dsm_registry.sql b/src/test/modules/test_dsm_registry/sql/test_dsm_registry.sql
index c2e25cddaae..a84beaec6c5 100644
--- a/src/test/modules/test_dsm_registry/sql/test_dsm_registry.sql
+++ b/src/test/modules/test_dsm_registry/sql/test_dsm_registry.sql
@@ -4,3 +4,5 @@ SELECT set_val_in_hash('test', '1414');
\c
SELECT get_val_in_shmem();
SELECT get_val_in_hash('test');
+\c
+SELECT name, type, size > 0 OR size ISNULL as size FROM pg_dsm_registry_allocations WHERE name like 'test_dsm_registry%';
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index 6cf828ca8d0..dce8c672b40 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -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,
--
2.49.0