Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commited10f32

Browse files
committed
Add pg_shmem_allocations view.
This tells you about allocations that have been made from the mainshared memory segment. The original patch also tried to show informationabout dynamic shared memory allocation as well, but I decided toleave that problem for another time.Andres Freund and Robert Haas, reviewed by Michael Paquier, MartiRaudsepp, Tom Lane, Álvaro Herrera, and Kyotaro Horiguchi.Discussion:http://postgr.es/m/20140504114417.GM12715@awork2.anarazel.de
1 parent5acf6d8 commited10f32

File tree

7 files changed

+212
-4
lines changed

7 files changed

+212
-4
lines changed

‎doc/src/sgml/catalogs.sgml

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8362,6 +8362,11 @@ SCRAM-SHA-256$<replaceable>&lt;iteration count&gt;</replaceable>:<replaceable>&l
83628362
<entry>planner statistics</entry>
83638363
</row>
83648364

8365+
<row>
8366+
<entry><link linkend="view-pg-shmem-allocations"><structname>pg_shmem_allocations</structname></link></entry>
8367+
<entry>shared memory allocations</entry>
8368+
</row>
8369+
83658370
<row>
83668371
<entry><link linkend="view-pg-stats-ext"><structname>pg_stats_ext</structname></link></entry>
83678372
<entry>extended planner statistics</entry>
@@ -10748,6 +10753,86 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
1074810753

1074910754
</sect1>
1075010755

10756+
<sect1 id="view-pg-shmem-allocations">
10757+
<title><structname>pg_shmem_allocations</structname></title>
10758+
10759+
<indexterm zone="view-pg-shmem-allocations">
10760+
<primary>pg_shmem_allocations</primary>
10761+
</indexterm>
10762+
10763+
<para>
10764+
The <structname>pg_shmem_allocations</structname> view shows allocations
10765+
made from the server's main shared memory segment. This includes both
10766+
memory allocated by <productname>postgres</productname> itself and memory
10767+
allocated by extensions using the mechanisms detailed in
10768+
<xref linkend="xfunc-shared-addin" />.
10769+
</para>
10770+
10771+
<para>
10772+
Note that this view does not include memory allocated using the dynamic
10773+
shared memory infrastructure.
10774+
</para>
10775+
10776+
<table>
10777+
<title><structname>pg_shmem_allocations</structname> Columns</title>
10778+
10779+
<tgroup cols="3">
10780+
<thead>
10781+
<row>
10782+
<entry>Name</entry>
10783+
<entry>Type</entry>
10784+
<entry>Description</entry>
10785+
</row>
10786+
</thead>
10787+
10788+
<tbody>
10789+
<row>
10790+
<entry><structfield>name</structfield></entry>
10791+
<entry><type>text</type></entry>
10792+
<entry>The name of the shared memory allocation. NULL for unused memory
10793+
and <literal>&lt;anonymous&gt;</literal> for anonymous
10794+
allocations.</entry>
10795+
</row>
10796+
10797+
<row>
10798+
<entry><structfield>off</structfield></entry>
10799+
<entry><type>bigint</type></entry>
10800+
<entry>The offset at which the allocation starts. NULL for anonymous
10801+
allocations and unused memory.</entry>
10802+
</row>
10803+
10804+
<row>
10805+
<entry><structfield>size</structfield></entry>
10806+
<entry><type>bigint</type></entry>
10807+
<entry>Size of the allocation</entry>
10808+
</row>
10809+
10810+
<row>
10811+
<entry><structfield>allocated_size</structfield></entry>
10812+
<entry><type>bigint</type></entry>
10813+
<entry>Size of the allocation including padding. For anonymous
10814+
allocations, no information about padding is available, so the
10815+
<literal>size</literal> and <literal>allocated_size</literal> columns
10816+
will always be equal. Padding is not meaningful for free memory, so
10817+
the columns will be equal in that case also.</entry>
10818+
</row>
10819+
</tbody>
10820+
</tgroup>
10821+
</table>
10822+
10823+
<para>
10824+
Anonymous allocations are allocations that have been made
10825+
with <literal>ShmemAlloc()</literal> directly, rather than via
10826+
<literal>ShmemInitStruct()</literal> or
10827+
<literal>ShmemInitHash()</literal>.
10828+
</para>
10829+
10830+
<para>
10831+
By default, the <structname>pg_shmem_allocations</structname> view can be
10832+
read only by superusers.
10833+
</para>
10834+
</sect1>
10835+
1075110836
<sect1 id="view-pg-stats">
1075210837
<title><structname>pg_stats</structname></title>
1075310838

‎doc/src/sgml/xfunc.sgml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3239,7 +3239,7 @@ CREATE FUNCTION make_array(anyelement) RETURNS anyarray
32393239
</para>
32403240
</sect2>
32413241

3242-
<sect2>
3242+
<sect2 id="xfunc-shared-addin">
32433243
<title>Shared Memory and LWLocks</title>
32443244

32453245
<para>

‎src/backend/catalog/system_views.sql

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,12 @@ CREATE VIEW pg_config AS
547547
REVOKE ALLon pg_configFROM PUBLIC;
548548
REVOKE EXECUTEON FUNCTION pg_config()FROM PUBLIC;
549549

550+
CREATEVIEWpg_shmem_allocationsAS
551+
SELECT*FROM pg_get_shmem_allocations();
552+
553+
REVOKE ALLON pg_shmem_allocationsFROM PUBLIC;
554+
REVOKE EXECUTEON FUNCTION pg_get_shmem_allocations()FROM PUBLIC;
555+
550556
-- Statistics views
551557

552558
CREATEVIEWpg_stat_all_tablesAS

‎src/backend/storage/ipc/shmem.c

Lines changed: 104 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,16 @@
6666
#include"postgres.h"
6767

6868
#include"access/transam.h"
69+
#include"fmgr.h"
70+
#include"funcapi.h"
6971
#include"miscadmin.h"
7072
#include"storage/lwlock.h"
7173
#include"storage/pg_shmem.h"
7274
#include"storage/shmem.h"
7375
#include"storage/spin.h"
76+
#include"utils/builtins.h"
7477

78+
staticvoid*ShmemAllocRaw(Sizesize,Size*allocated_size);
7579

7680
/* shared memory global variables */
7781

@@ -157,8 +161,9 @@ void *
157161
ShmemAlloc(Sizesize)
158162
{
159163
void*newSpace;
164+
Sizeallocated_size;
160165

161-
newSpace=ShmemAllocNoError(size);
166+
newSpace=ShmemAllocRaw(size,&allocated_size);
162167
if (!newSpace)
163168
ereport(ERROR,
164169
(errcode(ERRCODE_OUT_OF_MEMORY),
@@ -174,6 +179,20 @@ ShmemAlloc(Size size)
174179
*/
175180
void*
176181
ShmemAllocNoError(Sizesize)
182+
{
183+
Sizeallocated_size;
184+
185+
returnShmemAllocRaw(size,&allocated_size);
186+
}
187+
188+
/*
189+
* ShmemAllocRaw -- allocate align chunk and return allocated size
190+
*
191+
* Also sets *allocated_size to the number of bytes allocated, which will
192+
* be equal to the number requested plus any padding we choose to add.
193+
*/
194+
staticvoid*
195+
ShmemAllocRaw(Sizesize,Size*allocated_size)
177196
{
178197
SizenewStart;
179198
SizenewFree;
@@ -191,6 +210,7 @@ ShmemAllocNoError(Size size)
191210
* won't be sufficient.
192211
*/
193212
size=CACHELINEALIGN(size);
213+
*allocated_size=size;
194214

195215
Assert(ShmemSegHdr!=NULL);
196216

@@ -441,8 +461,10 @@ ShmemInitStruct(const char *name, Size size, bool *foundPtr)
441461
}
442462
else
443463
{
464+
Sizeallocated_size;
465+
444466
/* It isn't in the table yet. allocate and initialize it */
445-
structPtr=ShmemAllocNoError(size);
467+
structPtr=ShmemAllocRaw(size,&allocated_size);
446468
if (structPtr==NULL)
447469
{
448470
/* out of memory; remove the failed ShmemIndex entry */
@@ -455,6 +477,7 @@ ShmemInitStruct(const char *name, Size size, bool *foundPtr)
455477
name,size)));
456478
}
457479
result->size=size;
480+
result->allocated_size=allocated_size;
458481
result->location=structPtr;
459482
}
460483

@@ -503,3 +526,82 @@ mul_size(Size s1, Size s2)
503526
errmsg("requested shared memory size overflows size_t")));
504527
returnresult;
505528
}
529+
530+
/* SQL SRF showing allocated shared memory */
531+
Datum
532+
pg_get_shmem_allocations(PG_FUNCTION_ARGS)
533+
{
534+
#definePG_GET_SHMEM_SIZES_COLS 4
535+
ReturnSetInfo*rsinfo= (ReturnSetInfo*)fcinfo->resultinfo;
536+
TupleDesctupdesc;
537+
Tuplestorestate*tupstore;
538+
MemoryContextper_query_ctx;
539+
MemoryContextoldcontext;
540+
HASH_SEQ_STATUShstat;
541+
ShmemIndexEnt*ent;
542+
Sizenamed_allocated=0;
543+
Datumvalues[PG_GET_SHMEM_SIZES_COLS];
544+
boolnulls[PG_GET_SHMEM_SIZES_COLS];
545+
546+
/* check to see if caller supports us returning a tuplestore */
547+
if (rsinfo==NULL|| !IsA(rsinfo,ReturnSetInfo))
548+
ereport(ERROR,
549+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
550+
errmsg("set-valued function called in context that cannot accept a set")));
551+
if (!(rsinfo->allowedModes&SFRM_Materialize))
552+
ereport(ERROR,
553+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
554+
errmsg("materialize mode required, but it is not allowed in this context")));
555+
556+
/* Build a tuple descriptor for our result type */
557+
if (get_call_result_type(fcinfo,NULL,&tupdesc)!=TYPEFUNC_COMPOSITE)
558+
elog(ERROR,"return type must be a row type");
559+
560+
per_query_ctx=rsinfo->econtext->ecxt_per_query_memory;
561+
oldcontext=MemoryContextSwitchTo(per_query_ctx);
562+
563+
tupstore=tuplestore_begin_heap(true, false,work_mem);
564+
rsinfo->returnMode=SFRM_Materialize;
565+
rsinfo->setResult=tupstore;
566+
rsinfo->setDesc=tupdesc;
567+
568+
MemoryContextSwitchTo(oldcontext);
569+
570+
LWLockAcquire(ShmemIndexLock,LW_SHARED);
571+
572+
hash_seq_init(&hstat,ShmemIndex);
573+
574+
/* output all allocated entries */
575+
memset(nulls,0,sizeof(nulls));
576+
while ((ent= (ShmemIndexEnt*)hash_seq_search(&hstat))!=NULL)
577+
{
578+
values[0]=CStringGetTextDatum(ent->key);
579+
values[1]=Int64GetDatum((char*)ent->location- (char*)ShmemSegHdr);
580+
values[2]=Int64GetDatum(ent->size);
581+
values[3]=Int64GetDatum(ent->allocated_size);
582+
named_allocated+=ent->allocated_size;
583+
584+
tuplestore_putvalues(tupstore,tupdesc,values,nulls);
585+
}
586+
587+
/* output shared memory allocated but not counted via the shmem index */
588+
values[0]=CStringGetTextDatum("<anonymous>");
589+
nulls[1]= true;
590+
values[2]=Int64GetDatum(ShmemSegHdr->freeoffset-named_allocated);
591+
values[3]=values[2];
592+
tuplestore_putvalues(tupstore,tupdesc,values,nulls);
593+
594+
/* output as-of-yet unused shared memory */
595+
nulls[0]= true;
596+
values[1]=Int64GetDatum(ShmemSegHdr->freeoffset);
597+
nulls[1]= false;
598+
values[2]=Int64GetDatum(ShmemSegHdr->totalsize-ShmemSegHdr->freeoffset);
599+
values[3]=values[2];
600+
tuplestore_putvalues(tupstore,tupdesc,values,nulls);
601+
602+
LWLockRelease(ShmemIndexLock);
603+
604+
tuplestore_donestoring(tupstore);
605+
606+
return (Datum)0;
607+
}

‎src/include/catalog/pg_proc.dat

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7663,6 +7663,15 @@
76637663
proparallel => 'r', prorettype => 'float8', proargtypes => '',
76647664
prosrc => 'pg_notification_queue_usage' },
76657665

7666+
# shared memory usage
7667+
{ oid => '8613',
7668+
descr => 'allocations from the main shared memory segment',
7669+
proname => 'pg_get_shmem_allocations', 'prorows' => 50, 'proretset' => 't',
7670+
provolatile => 'v', 'prorettype' => 'record', 'proargtypes' => '',
7671+
proallargtypes => '{text,int8,int8,int8}', proargmodes => '{o,o,o,o}',
7672+
proargnames => '{name,off,size,allocated_size}',
7673+
prosrc => 'pg_get_shmem_allocations' },
7674+
76667675
# non-persistent series generator
76677676
{ oid => '1066', descr => 'non-persistent series generator',
76687677
proname => 'generate_series', prorows => '1000',

‎src/include/storage/shmem.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ typedef struct
5959
{
6060
charkey[SHMEM_INDEX_KEYSIZE];/* string name */
6161
void*location;/* location in shared mem */
62-
Sizesize;/* # bytes allocated for the structure */
62+
Sizesize;/* # bytes requested for the structure */
63+
Sizeallocated_size;/* # bytes actually allocated */
6364
}ShmemIndexEnt;
6465

6566
/*

‎src/test/regress/expected/rules.out

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1721,6 +1721,11 @@ pg_shadow| SELECT pg_authid.rolname AS usename,
17211721
FROM (pg_authid
17221722
LEFT JOIN pg_db_role_setting s ON (((pg_authid.oid = s.setrole) AND (s.setdatabase = (0)::oid))))
17231723
WHERE pg_authid.rolcanlogin;
1724+
pg_shmem_allocations| SELECT pg_get_shmem_allocations.name,
1725+
pg_get_shmem_allocations.off,
1726+
pg_get_shmem_allocations.size,
1727+
pg_get_shmem_allocations.allocated_size
1728+
FROM pg_get_shmem_allocations() pg_get_shmem_allocations(name, off, size, allocated_size);
17241729
pg_stat_activity| SELECT s.datid,
17251730
d.datname,
17261731
s.pid,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp