Skip to content

Commit 167ed80

Browse files
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
1 parent f5a987c commit 167ed80

File tree

10 files changed

+187
-3
lines changed

10 files changed

+187
-3
lines changed

doc/src/sgml/system-views.sgml

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,11 @@
8181
<entry>open cursors</entry>
8282
</row>
8383

84+
<row>
85+
<entry><link linkend="view-pg-dsm-registry-allocations"><structname>pg_dsm_registry_allocations</structname></link></entry>
86+
<entry>shared memory allocations tracked in the DSM registry</entry>
87+
</row>
88+
8489
<row>
8590
<entry><link linkend="view-pg-file-settings"><structname>pg_file_settings</structname></link></entry>
8691
<entry>summary of configuration file contents</entry>
@@ -1086,6 +1091,75 @@ AND c1.path[c2.level] = c2.path[c2.level];
10861091

10871092
</sect1>
10881093

1094+
<sect1 id="view-pg-dsm-registry-allocations">
1095+
<title><structname>pg_dsm_registry_allocations</structname></title>
1096+
1097+
<indexterm zone="view-pg-dsm-registry-allocations">
1098+
<primary>pg_dsm_registry_allocations</primary>
1099+
</indexterm>
1100+
1101+
<para>
1102+
The <structname>pg_dsm_registry_allocations</structname> view shows shared
1103+
memory allocations tracked in the dynamic shared memory (DSM) registry.
1104+
This includes memory allocated by extensions using the mechanisms detailed
1105+
in <xref linkend="xfunc-shared-addin-after-startup" />.
1106+
</para>
1107+
1108+
<table>
1109+
<title><structname>pg_dsm_registry_allocations</structname> Columns</title>
1110+
<tgroup cols="1">
1111+
<thead>
1112+
<row>
1113+
<entry role="catalog_table_entry"><para role="column_definition">
1114+
Column Type
1115+
</para>
1116+
<para>
1117+
Description
1118+
</para></entry>
1119+
</row>
1120+
</thead>
1121+
1122+
<tbody>
1123+
<row>
1124+
<entry role="catalog_table_entry"><para role="column_definition">
1125+
<structfield>name</structfield> <type>text</type>
1126+
</para>
1127+
<para>
1128+
The name of the allocation in the DSM registry.
1129+
</para></entry>
1130+
</row>
1131+
1132+
<row>
1133+
<entry role="catalog_table_entry"><para role="column_definition">
1134+
<structfield>type</structfield> <type>text</type>
1135+
</para>
1136+
<para>
1137+
The type of allocation. Possible values are <literal>segment</literal>,
1138+
<literal>area</literal>, and <literal>hash</literal>, which correspond
1139+
to dynamic shared memory segments, areas, and hash tables, respectively.
1140+
</para></entry>
1141+
</row>
1142+
1143+
<row>
1144+
<entry role="catalog_table_entry"><para role="column_definition">
1145+
<structfield>size</structfield> <type>int8</type>
1146+
</para>
1147+
<para>
1148+
Size of the allocation in bytes. NULL for entries of type
1149+
<literal>area</literal> and <literal>hash</literal>.
1150+
</para></entry>
1151+
</row>
1152+
</tbody>
1153+
</tgroup>
1154+
</table>
1155+
1156+
<para>
1157+
By default, the <structname>pg_dsm_registry_allocations</structname> view
1158+
can be read only by superusers or roles with privileges of the
1159+
<literal>pg_read_all_stats</literal> role.
1160+
</para>
1161+
</sect1>
1162+
10891163
<sect1 id="view-pg-file-settings">
10901164
<title><structname>pg_file_settings</structname></title>
10911165

src/backend/catalog/system_views.sql

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,14 @@ GRANT SELECT ON pg_shmem_allocations_numa TO pg_read_all_stats;
666666
REVOKE EXECUTE ON FUNCTION pg_get_shmem_allocations_numa() FROM PUBLIC;
667667
GRANT EXECUTE ON FUNCTION pg_get_shmem_allocations_numa() TO pg_read_all_stats;
668668

669+
CREATE VIEW pg_dsm_registry_allocations AS
670+
SELECT * FROM pg_get_dsm_registry_allocations();
671+
672+
REVOKE ALL ON pg_dsm_registry_allocations FROM PUBLIC;
673+
GRANT SELECT ON pg_dsm_registry_allocations TO pg_read_all_stats;
674+
REVOKE EXECUTE ON FUNCTION pg_get_dsm_registry_allocations() FROM PUBLIC;
675+
GRANT EXECUTE ON FUNCTION pg_get_dsm_registry_allocations() TO pg_read_all_stats;
676+
669677
CREATE VIEW pg_backend_memory_contexts AS
670678
SELECT * FROM pg_get_backend_memory_contexts();
671679

src/backend/storage/ipc/dsm_registry.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,12 @@
4040

4141
#include "postgres.h"
4242

43+
#include "funcapi.h"
4344
#include "lib/dshash.h"
4445
#include "storage/dsm_registry.h"
4546
#include "storage/lwlock.h"
4647
#include "storage/shmem.h"
48+
#include "utils/builtins.h"
4749
#include "utils/memutils.h"
4850

4951
#define DSMR_NAME_LEN 128
@@ -88,6 +90,13 @@ typedef enum DSMREntryType
8890
DSMR_ENTRY_TYPE_DSH,
8991
} DSMREntryType;
9092

93+
static const char *const DSMREntryTypeNames[] =
94+
{
95+
[DSMR_ENTRY_TYPE_DSM] = "segment",
96+
[DSMR_ENTRY_TYPE_DSA] = "area",
97+
[DSMR_ENTRY_TYPE_DSH] = "hash",
98+
};
99+
91100
typedef struct DSMRegistryEntry
92101
{
93102
char name[DSMR_NAME_LEN];
@@ -435,3 +444,43 @@ GetNamedDSHash(const char *name, const dshash_parameters *params, bool *found)
435444

436445
return ret;
437446
}
447+
448+
Datum
449+
pg_get_dsm_registry_allocations(PG_FUNCTION_ARGS)
450+
{
451+
ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
452+
DSMRegistryEntry *entry;
453+
MemoryContext oldcontext;
454+
dshash_seq_status status;
455+
456+
InitMaterializedSRF(fcinfo, MAT_SRF_USE_EXPECTED_DESC);
457+
458+
/* Be sure any local memory allocated by DSM/DSA routines is persistent. */
459+
oldcontext = MemoryContextSwitchTo(TopMemoryContext);
460+
init_dsm_registry();
461+
MemoryContextSwitchTo(oldcontext);
462+
463+
dshash_seq_init(&status, dsm_registry_table, false);
464+
while ((entry = dshash_seq_next(&status)) != NULL)
465+
{
466+
Datum vals[3];
467+
bool nulls[3] = {0};
468+
469+
vals[0] = CStringGetTextDatum(entry->name);
470+
vals[1] = CStringGetTextDatum(DSMREntryTypeNames[entry->type]);
471+
472+
/*
473+
* Since we can't know the size of DSA/dshash entries without first
474+
* attaching to them, return NULL for those.
475+
*/
476+
if (entry->type == DSMR_ENTRY_TYPE_DSM)
477+
vals[2] = Int64GetDatum(entry->data.dsm.size);
478+
else
479+
nulls[2] = true;
480+
481+
tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, vals, nulls);
482+
}
483+
dshash_seq_term(&status);
484+
485+
return (Datum) 0;
486+
}

src/include/catalog/catversion.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,6 @@
5757
*/
5858

5959
/* yyyymmddN */
60-
#define CATALOG_VERSION_NO 202506301
60+
#define CATALOG_VERSION_NO 202507091
6161

6262
#endif

src/include/catalog/pg_proc.dat

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8572,6 +8572,14 @@
85728572
proargnames => '{name,numa_node,size}',
85738573
prosrc => 'pg_get_shmem_allocations_numa' },
85748574

8575+
{ oid => '9314',
8576+
descr => 'shared memory allocations tracked in the DSM registry',
8577+
proname => 'pg_get_dsm_registry_allocations', prorows => '50',
8578+
proretset => 't', provolatile => 'v', prorettype => 'record',
8579+
proargtypes => '', proallargtypes => '{text,text,int8}',
8580+
proargmodes => '{o,o,o}', proargnames => '{name,type,size}',
8581+
prosrc => 'pg_get_dsm_registry_allocations' },
8582+
85758583
# memory context of local backend
85768584
{ oid => '2282',
85778585
descr => 'information about all memory contexts of local backend',

src/test/modules/test_dsm_registry/expected/test_dsm_registry.out

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
SELECT name, type, size IS DISTINCT FROM 0 AS size
2+
FROM pg_dsm_registry_allocations
3+
WHERE name like 'test_dsm_registry%' ORDER BY name;
4+
name | type | size
5+
------+------+------
6+
(0 rows)
7+
18
CREATE EXTENSION test_dsm_registry;
29
SELECT set_val_in_shmem(1236);
310
set_val_in_shmem
@@ -24,3 +31,14 @@ SELECT get_val_in_hash('test');
2431
1414
2532
(1 row)
2633

34+
\c
35+
SELECT name, type, size IS DISTINCT FROM 0 AS size
36+
FROM pg_dsm_registry_allocations
37+
WHERE name like 'test_dsm_registry%' ORDER BY name;
38+
name | type | size
39+
------------------------+---------+------
40+
test_dsm_registry_dsa | area | t
41+
test_dsm_registry_dsm | segment | t
42+
test_dsm_registry_hash | hash | t
43+
(3 rows)
44+
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
1+
SELECT name, type, size IS DISTINCT FROM 0 AS size
2+
FROM pg_dsm_registry_allocations
3+
WHERE name like 'test_dsm_registry%' ORDER BY name;
14
CREATE EXTENSION test_dsm_registry;
25
SELECT set_val_in_shmem(1236);
36
SELECT set_val_in_hash('test', '1414');
47
\c
58
SELECT get_val_in_shmem();
69
SELECT get_val_in_hash('test');
10+
\c
11+
SELECT name, type, size IS DISTINCT FROM 0 AS size
12+
FROM pg_dsm_registry_allocations
13+
WHERE name like 'test_dsm_registry%' ORDER BY name;

src/test/regress/expected/privileges.out

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3220,7 +3220,8 @@ REVOKE MAINTAIN ON lock_table FROM regress_locktable_user;
32203220
DROP TABLE lock_table;
32213221
DROP USER regress_locktable_user;
32223222
-- test to check privileges of system views pg_shmem_allocations,
3223-
-- pg_shmem_allocations_numa and pg_backend_memory_contexts.
3223+
-- pg_shmem_allocations_numa, pg_dsm_registry_allocations, and
3224+
-- pg_backend_memory_contexts.
32243225
-- switch to superuser
32253226
\c -
32263227
CREATE ROLE regress_readallstats;
@@ -3248,6 +3249,12 @@ SELECT has_table_privilege('regress_readallstats','pg_shmem_allocations_numa','S
32483249
f
32493250
(1 row)
32503251

3252+
SELECT has_table_privilege('regress_readallstats','pg_dsm_registry_allocations','SELECT'); -- no
3253+
has_table_privilege
3254+
---------------------
3255+
f
3256+
(1 row)
3257+
32513258
GRANT pg_read_all_stats TO regress_readallstats;
32523259
SELECT has_table_privilege('regress_readallstats','pg_aios','SELECT'); -- yes
32533260
has_table_privilege
@@ -3273,6 +3280,12 @@ SELECT has_table_privilege('regress_readallstats','pg_shmem_allocations_numa','S
32733280
t
32743281
(1 row)
32753282

3283+
SELECT has_table_privilege('regress_readallstats','pg_dsm_registry_allocations','SELECT'); -- yes
3284+
has_table_privilege
3285+
---------------------
3286+
t
3287+
(1 row)
3288+
32763289
-- run query to ensure that functions within views can be executed
32773290
SET ROLE regress_readallstats;
32783291
SELECT COUNT(*) >= 0 AS ok FROM pg_aios;

src/test/regress/expected/rules.out

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1340,6 +1340,10 @@ pg_cursors| SELECT name,
13401340
is_scrollable,
13411341
creation_time
13421342
FROM pg_cursor() c(name, statement, is_holdable, is_binary, is_scrollable, creation_time);
1343+
pg_dsm_registry_allocations| SELECT name,
1344+
type,
1345+
size
1346+
FROM pg_get_dsm_registry_allocations() pg_get_dsm_registry_allocations(name, type, size);
13431347
pg_file_settings| SELECT sourcefile,
13441348
sourceline,
13451349
seqno,

src/test/regress/sql/privileges.sql

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1948,7 +1948,8 @@ DROP TABLE lock_table;
19481948
DROP USER regress_locktable_user;
19491949

19501950
-- test to check privileges of system views pg_shmem_allocations,
1951-
-- pg_shmem_allocations_numa and pg_backend_memory_contexts.
1951+
-- pg_shmem_allocations_numa, pg_dsm_registry_allocations, and
1952+
-- pg_backend_memory_contexts.
19521953

19531954
-- switch to superuser
19541955
\c -
@@ -1959,13 +1960,15 @@ SELECT has_table_privilege('regress_readallstats','pg_aios','SELECT'); -- no
19591960
SELECT has_table_privilege('regress_readallstats','pg_backend_memory_contexts','SELECT'); -- no
19601961
SELECT has_table_privilege('regress_readallstats','pg_shmem_allocations','SELECT'); -- no
19611962
SELECT has_table_privilege('regress_readallstats','pg_shmem_allocations_numa','SELECT'); -- no
1963+
SELECT has_table_privilege('regress_readallstats','pg_dsm_registry_allocations','SELECT'); -- no
19621964

19631965
GRANT pg_read_all_stats TO regress_readallstats;
19641966

19651967
SELECT has_table_privilege('regress_readallstats','pg_aios','SELECT'); -- yes
19661968
SELECT has_table_privilege('regress_readallstats','pg_backend_memory_contexts','SELECT'); -- yes
19671969
SELECT has_table_privilege('regress_readallstats','pg_shmem_allocations','SELECT'); -- yes
19681970
SELECT has_table_privilege('regress_readallstats','pg_shmem_allocations_numa','SELECT'); -- yes
1971+
SELECT has_table_privilege('regress_readallstats','pg_dsm_registry_allocations','SELECT'); -- yes
19691972

19701973
-- run query to ensure that functions within views can be executed
19711974
SET ROLE regress_readallstats;

0 commit comments

Comments
 (0)