mirror of
https://github.com/postgres/postgres.git
synced 2026-07-08 01:01:01 -04:00
Add system view pg_stat_kind_info
This commit adds support for pg_stat_kind_info, that exposes at SQL level data about the statistics kinds registered into a backend: - Meta-data of a stats kind (built-in or custom, some properties). - Number of entries, if tracking is enabled. We have discussed the possibility of more fields (like shared memory size for a single entry); this adds the minimum agreed on. This is in spirit similar to pg_get_loaded_modules() for custom stats kinds, this view providing detailed information about the stats kinds when registered through shared_preload_libraries. Bump catalog version. Author: Tristan Partin <tristan@partin.io> Reviewed-by: Bertrand Drouvot <bertranddrouvot.pg@gmail.com> Reviewed-by: Sami Imseih <samimseih@gmail.com> Reviewed-by: Michael Paquier <michael@paquier.xyz> Discussion: https://postgr.es/m/DI6OFGHJ1B69.25YVDEP3BABRH@partin.io
This commit is contained in:
parent
2e606d75c0
commit
3b066de6c0
11 changed files with 273 additions and 2 deletions
|
|
@ -509,6 +509,16 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser
|
|||
</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><structname>pg_stat_kind_info</structname><indexterm><primary>pg_stat_kind_info</primary></indexterm></entry>
|
||||
<entry>
|
||||
One row for each registered statistics kind, showing information
|
||||
about each kind.
|
||||
See <link linkend="monitoring-pg-stat-kind-info-view">
|
||||
<structname>pg_stat_kind_info</structname></link> for details.
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><structname>pg_stat_lock</structname><indexterm><primary>pg_stat_lock</primary></indexterm></entry>
|
||||
<entry>
|
||||
|
|
@ -3303,6 +3313,124 @@ description | Waiting for a newly initialized WAL file to reach durable storage
|
|||
</sect2>
|
||||
|
||||
|
||||
<sect2 id="monitoring-pg-stat-kind-info-view">
|
||||
<title><structname>pg_stat_kind_info</structname></title>
|
||||
|
||||
<indexterm>
|
||||
<primary>pg_stat_kind_info</primary>
|
||||
</indexterm>
|
||||
|
||||
<para>
|
||||
The <structname>pg_stat_kind_info</structname> view contains one row for
|
||||
each registered statistics kind, including both built-in and custom kinds.
|
||||
</para>
|
||||
|
||||
<table id="pg-stat-kind-info-view" xreflabel="pg_stat_kind_info">
|
||||
<title><structname>pg_stat_kind_info</structname> View</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>id</structfield> <type>integer</type>
|
||||
</para>
|
||||
<para>
|
||||
Numeric identifier of the statistics kind.
|
||||
</para>
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry role="catalog_table_entry">
|
||||
<para role="column_definition">
|
||||
<structfield>name</structfield> <type>text</type>
|
||||
</para>
|
||||
<para>
|
||||
Name of the statistics kind.
|
||||
</para>
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry role="catalog_table_entry">
|
||||
<para role="column_definition">
|
||||
<structfield>builtin</structfield> <type>boolean</type>
|
||||
</para>
|
||||
<para>
|
||||
True if this is a built-in statistics kind, false if it was registered
|
||||
by an extension.
|
||||
</para>
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry role="catalog_table_entry">
|
||||
<para role="column_definition">
|
||||
<structfield>fixed_amount</structfield> <type>boolean</type>
|
||||
</para>
|
||||
<para>
|
||||
True if this kind tracks a fixed amount of data (a single, statically
|
||||
allocated entry), false if it tracks a variable number of entries
|
||||
keyed by object identifier.
|
||||
</para>
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry role="catalog_table_entry">
|
||||
<para role="column_definition">
|
||||
<structfield>accessed_across_databases</structfield> <type>boolean</type>
|
||||
</para>
|
||||
<para>
|
||||
True if entries of this kind are accessed across databases (cluster-wide
|
||||
statistics), false if they are scoped to a single database.
|
||||
</para>
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry role="catalog_table_entry">
|
||||
<para role="column_definition">
|
||||
<structfield>write_to_file</structfield> <type>boolean</type>
|
||||
</para>
|
||||
<para>
|
||||
True if entries of this kind are persisted to the statistics file at
|
||||
shutdown and reloaded on startup, false if they are kept only in
|
||||
shared memory.
|
||||
</para>
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry role="catalog_table_entry">
|
||||
<para role="column_definition">
|
||||
<structfield>entry_count</structfield> <type>bigint</type>
|
||||
</para>
|
||||
<para>
|
||||
Number of tracked entries for this kind. For variable-numbered kinds,
|
||||
this is the number of objects currently tracked.
|
||||
<literal>NULL</literal> for fixed-sized statistics kinds, or if the
|
||||
kind does not track entry counts.
|
||||
</para>
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="monitoring-pg-stat-lock-view">
|
||||
<title><structname>pg_stat_lock</structname></title>
|
||||
|
||||
|
|
|
|||
|
|
@ -1282,6 +1282,17 @@ SELECT
|
|||
b.stats_reset
|
||||
FROM pg_stat_get_io() b;
|
||||
|
||||
CREATE VIEW pg_stat_kind_info AS
|
||||
SELECT
|
||||
k.id,
|
||||
k.name,
|
||||
k.builtin,
|
||||
k.fixed_amount,
|
||||
k.accessed_across_databases,
|
||||
k.write_to_file,
|
||||
k.entry_count
|
||||
FROM pg_stat_get_kind_info() k;
|
||||
|
||||
CREATE VIEW pg_stat_wal AS
|
||||
SELECT
|
||||
w.wal_records,
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ OBJS = \
|
|||
pgstat_database.o \
|
||||
pgstat_function.o \
|
||||
pgstat_io.o \
|
||||
pgstat_kind.o \
|
||||
pgstat_lock.o \
|
||||
pgstat_relation.o \
|
||||
pgstat_replslot.o \
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ backend_sources += files(
|
|||
'pgstat_database.c',
|
||||
'pgstat_function.c',
|
||||
'pgstat_io.c',
|
||||
'pgstat_kind.c',
|
||||
'pgstat_lock.c',
|
||||
'pgstat_relation.c',
|
||||
'pgstat_replslot.c',
|
||||
|
|
|
|||
72
src/backend/utils/activity/pgstat_kind.c
Normal file
72
src/backend/utils/activity/pgstat_kind.c
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* pgstat_kind.c
|
||||
* Functions related to statistics kinds.
|
||||
*
|
||||
* Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* src/backend/utils/activity/pgstat_kind.c
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#include "postgres.h"
|
||||
|
||||
#include "fmgr.h"
|
||||
#include "funcapi.h"
|
||||
#include "utils/builtins.h"
|
||||
#include "utils/fmgrprotos.h"
|
||||
#include "utils/pgstat_internal.h"
|
||||
#include "utils/pgstat_kind.h"
|
||||
#include "utils/tuplestore.h"
|
||||
|
||||
|
||||
/*
|
||||
* pg_stat_get_kind_info
|
||||
*
|
||||
* Get information about the statistics kinds registered into the system.
|
||||
*/
|
||||
Datum
|
||||
pg_stat_get_kind_info(PG_FUNCTION_ARGS)
|
||||
{
|
||||
#define PG_STAT_KIND_INFO_COLS 7
|
||||
ReturnSetInfo *rsinfo;
|
||||
|
||||
InitMaterializedSRF(fcinfo, 0);
|
||||
rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
|
||||
|
||||
for (int kind = PGSTAT_KIND_MIN; kind <= PGSTAT_KIND_MAX; kind++)
|
||||
{
|
||||
Datum values[PG_STAT_KIND_INFO_COLS] = {0};
|
||||
bool nulls[PG_STAT_KIND_INFO_COLS] = {0};
|
||||
const PgStat_KindInfo *info;
|
||||
|
||||
info = pgstat_get_kind_info(kind);
|
||||
if (info == NULL)
|
||||
continue;
|
||||
|
||||
values[0] = Int32GetDatum(kind);
|
||||
values[1] = CStringGetTextDatum(info->name);
|
||||
|
||||
values[2] = BoolGetDatum(pgstat_is_kind_builtin(kind));
|
||||
values[3] = BoolGetDatum(info->fixed_amount);
|
||||
values[4] = BoolGetDatum(info->accessed_across_databases);
|
||||
values[5] = BoolGetDatum(info->write_to_file);
|
||||
|
||||
/*
|
||||
* When track_entry_count is disabled, use NULL. Fixed-sized stats
|
||||
* kinds report NULL here.
|
||||
*/
|
||||
if (info->track_entry_count)
|
||||
values[6] = Int64GetDatum(pgstat_get_entry_count(kind));
|
||||
else
|
||||
nulls[6] = true;
|
||||
|
||||
tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls);
|
||||
}
|
||||
|
||||
return (Datum) 0;
|
||||
#undef PG_STAT_KIND_INFO_COLS
|
||||
}
|
||||
|
|
@ -57,6 +57,6 @@
|
|||
*/
|
||||
|
||||
/* yyyymmddN */
|
||||
#define CATALOG_VERSION_NO 202607011
|
||||
#define CATALOG_VERSION_NO 202607021
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -6078,6 +6078,14 @@
|
|||
proargnames => '{backend_pid,backend_type,object,context,reads,read_bytes,read_time,writes,write_bytes,write_time,writebacks,writeback_time,extends,extend_bytes,extend_time,hits,evictions,reuses,fsyncs,fsync_time,stats_reset}',
|
||||
prosrc => 'pg_stat_get_backend_io' },
|
||||
|
||||
{ oid => '8683', descr => 'statistics: information about statistics kinds',
|
||||
proname => 'pg_stat_get_kind_info', prorows => '20', proretset => 't',
|
||||
provolatile => 'v', proparallel => 'r', prorettype => 'record',
|
||||
proargtypes => '', proallargtypes => '{int4,text,bool,bool,bool,bool,int8}',
|
||||
proargmodes => '{o,o,o,o,o,o,o}',
|
||||
proargnames => '{id,name,builtin,fixed_amount,accessed_across_databases,write_to_file,entry_count}',
|
||||
prosrc => 'pg_stat_get_kind_info' },
|
||||
|
||||
{ oid => '1136', descr => 'statistics: information about WAL activity',
|
||||
proname => 'pg_stat_get_wal', proisstrict => 'f', provolatile => 's',
|
||||
proparallel => 'r', prorettype => 'record', proargtypes => '',
|
||||
|
|
|
|||
|
|
@ -27,6 +27,18 @@ $node->start;
|
|||
$node->safe_psql('postgres', q(CREATE EXTENSION test_custom_var_stats));
|
||||
$node->safe_psql('postgres', q(CREATE EXTENSION test_custom_fixed_stats));
|
||||
|
||||
# Verify custom stats kinds appear in pg_stat_kind_info.
|
||||
my $result = $node->safe_psql(
|
||||
'postgres',
|
||||
q(SELECT id, name, builtin, fixed_amount, accessed_across_databases,
|
||||
write_to_file
|
||||
FROM pg_stat_kind_info
|
||||
WHERE name LIKE 'test_custom%' ORDER BY id));
|
||||
is( $result,
|
||||
qq{25|test_custom_var_stats|f|f|t|t
|
||||
26|test_custom_fixed_stats|f|t|f|t},
|
||||
"custom stats kinds visible in pg_stat_kind_info");
|
||||
|
||||
# Create entries for variable-sized stats.
|
||||
$node->safe_psql('postgres',
|
||||
q(select test_custom_stats_var_create('entry1', 'Test entry 1')));
|
||||
|
|
@ -63,7 +75,7 @@ $node->safe_psql('postgres', q(select test_custom_stats_fixed_update()));
|
|||
$node->safe_psql('postgres', q(select test_custom_stats_fixed_update()));
|
||||
|
||||
# Test data reports.
|
||||
my $result = $node->safe_psql('postgres',
|
||||
$result = $node->safe_psql('postgres',
|
||||
q(select * from test_custom_stats_var_report('entry1')));
|
||||
is( $result,
|
||||
"entry1|2|Test entry 1",
|
||||
|
|
|
|||
|
|
@ -1967,6 +1967,14 @@ pg_stat_io| SELECT backend_type,
|
|||
fsync_time,
|
||||
stats_reset
|
||||
FROM pg_stat_get_io() b(backend_type, object, context, reads, read_bytes, read_time, writes, write_bytes, write_time, writebacks, writeback_time, extends, extend_bytes, extend_time, hits, evictions, reuses, fsyncs, fsync_time, stats_reset);
|
||||
pg_stat_kind_info| SELECT id,
|
||||
name,
|
||||
builtin,
|
||||
fixed_amount,
|
||||
accessed_across_databases,
|
||||
write_to_file,
|
||||
entry_count
|
||||
FROM pg_stat_get_kind_info() k(id, name, builtin, fixed_amount, accessed_across_databases, write_to_file, entry_count);
|
||||
pg_stat_lock| SELECT locktype,
|
||||
waits,
|
||||
wait_time,
|
||||
|
|
|
|||
|
|
@ -113,6 +113,29 @@ walwriter|wal|init
|
|||
walwriter|wal|normal
|
||||
(95 rows)
|
||||
\a
|
||||
-- List of registered statistics kinds.
|
||||
SELECT id, name, fixed_amount,
|
||||
accessed_across_databases AS across_db, write_to_file
|
||||
FROM pg_stat_kind_info
|
||||
WHERE builtin
|
||||
ORDER BY id;
|
||||
id | name | fixed_amount | across_db | write_to_file
|
||||
----+--------------+--------------+-----------+---------------
|
||||
1 | database | f | t | t
|
||||
2 | relation | f | f | t
|
||||
3 | function | f | f | t
|
||||
4 | replslot | f | t | t
|
||||
5 | subscription | f | t | t
|
||||
6 | backend | f | t | f
|
||||
7 | archiver | t | f | t
|
||||
8 | bgwriter | t | f | t
|
||||
9 | checkpointer | t | f | t
|
||||
10 | io | t | f | t
|
||||
11 | lock | t | f | t
|
||||
12 | slru | t | f | t
|
||||
13 | wal | t | f | t
|
||||
(13 rows)
|
||||
|
||||
-- ensure that both seqscan and indexscan plans are allowed
|
||||
SET enable_seqscan TO on;
|
||||
SET enable_indexscan TO on;
|
||||
|
|
|
|||
|
|
@ -14,6 +14,13 @@ SELECT backend_type, object, context FROM pg_stat_io
|
|||
ORDER BY backend_type COLLATE "C", object COLLATE "C", context COLLATE "C";
|
||||
\a
|
||||
|
||||
-- List of registered statistics kinds.
|
||||
SELECT id, name, fixed_amount,
|
||||
accessed_across_databases AS across_db, write_to_file
|
||||
FROM pg_stat_kind_info
|
||||
WHERE builtin
|
||||
ORDER BY id;
|
||||
|
||||
-- ensure that both seqscan and indexscan plans are allowed
|
||||
SET enable_seqscan TO on;
|
||||
SET enable_indexscan TO on;
|
||||
|
|
|
|||
Loading…
Reference in a new issue