v4-0001-Add-pg_dsm_registry_allocations-system-view.patch
application/octet-stream
Filename: v4-0001-Add-pg_dsm_registry_allocations-system-view.patch
Type: application/octet-stream
Part: 0
From f66d63613d8db0974c79a83a67184efa1dddfd93 Mon Sep 17 00:00:00 2001
From: Florents Tselai <florents.tselai@gmail.com>
Date: Wed, 4 Jun 2025 21:02:01 +0300
Subject: [PATCH v4] Add pg_dsm_registry_allocations system view
---
doc/src/sgml/system-views.sgml | 68 +++++++++++++++++++
src/backend/catalog/system_views.sql | 8 +++
src/backend/storage/ipc/dsm_registry.c | 34 ++++++++++
src/include/catalog/pg_proc.dat | 6 ++
.../expected/test_dsm_registry.out | 6 ++
.../sql/test_dsm_registry.sql | 2 +
src/test/regress/expected/rules.out | 3 +
7 files changed, 127 insertions(+)
diff --git a/doc/src/sgml/system-views.sgml b/doc/src/sgml/system-views.sgml
index b58c52ea50f..e41a7b5745f 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>
@@ -4146,6 +4151,69 @@ 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 DSM segments that have been allocated and tracked by
+ <productname>PostgreSQL</productname> during the server's operation.
+ </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 DSM allocation as registered in the DSM registry.
+ </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 allocated dynamic shared memory segment in bytes.
+ </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 08f780a2e63..64e62732f18 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 1d4fd31ffed..0650c70e173 100644
--- a/src/backend/storage/ipc/dsm_registry.c
+++ b/src/backend/storage/ipc/dsm_registry.c
@@ -26,10 +26,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"
typedef struct DSMRegistryCtxStruct
@@ -198,3 +200,35 @@ GetNamedDSMSegment(const char *name, size_t size,
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)
+ {
+ Datum values[2];
+ bool nulls[2] = {false, false};
+
+ values[0] = CStringGetTextDatum(entry->name);
+ values[1] = Int64GetDatum(entry->size);
+
+ 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 d3d28a263fa..bef92be8250 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -8541,6 +8541,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,int8}', proargmodes => '{o,o}',
+ proargnames => '{name,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 8ffbd343a05..3c279378b5b 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
@@ -12,3 +12,9 @@ SELECT get_val_in_shmem();
1236
(1 row)
+SELECT size > 0 FROM pg_dsm_registry_allocations WHERE name = 'test_dsm_registry';
+ ?column?
+----------
+ t
+(1 row)
+
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 b3351be0a16..d27ee2e6a1a 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
@@ -2,3 +2,5 @@ CREATE EXTENSION test_dsm_registry;
SELECT set_val_in_shmem(1236);
\c
SELECT get_val_in_shmem();
+
+SELECT size > 0 FROM pg_dsm_registry_allocations WHERE name = 'test_dsm_registry';
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index 6cf828ca8d0..893c5b2b933 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1340,6 +1340,9 @@ 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,
+ size
+ FROM pg_get_dsm_registry_allocations() pg_get_dsm_registry_allocations(name, size);
pg_file_settings| SELECT sourcefile,
sourceline,
seqno,
--
2.49.0