From 23c8c0c8f4721db693ef908c22f7cf754e6852a9 Mon Sep 17 00:00:00 2001 From: Michael Paquier <michael@paquier.xyz> Date: Sun, 12 Nov 2023 16:43:12 +0900 Subject: [PATCH] Add ability to reset all shared stats types in pg_stat_reset_shared() Currently, pg_stat_reset_shared() can use an argument to specify the target of statistics to reset, doing nothing for NULL as it is strict. This patch adds to pg_stat_reset_shared() the possibility to reset all the stats types already handled in this function rather than do nothing if the argument value given is NULL or if nothing is specified (proisstrict is switched to false). Like previously, SLRUs are not included in what gets reset. The idea to use NULL or no argument to control if all the shared stats already covered by this function should be reset has been proposed by Andres Freund. Bump catalog version. Author: Atsushi Torikoshi Reviewed-by: Kyotaro Horiguchi, Michael Paquier, Bharath Rupireddy, Matthias van de Meent Discussion: https://postgr.es/m/4291a55137ddda77cf7cc5f46e846daf@oss.nttdata.com --- doc/src/sgml/monitoring.sgml | 5 ++++- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/pgstatfuncs.c | 17 ++++++++++++++++- src/include/catalog/catversion.h | 2 +- src/include/catalog/pg_proc.dat | 5 +++-- src/test/regress/expected/stats.out | 15 ++++++++------- src/test/regress/sql/stats.sql | 15 ++++++++------- 7 files changed, 47 insertions(+), 19 deletions(-) diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml index e068f7e247..b8495b6498 100644 --- a/doc/src/sgml/monitoring.sgml +++ b/doc/src/sgml/monitoring.sgml @@ -4712,7 +4712,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage <indexterm> <primary>pg_stat_reset_shared</primary> </indexterm> - <function>pg_stat_reset_shared</function> ( <type>text</type> ) + <function>pg_stat_reset_shared</function> ( [ <parameter>target</parameter> <type>text</type> <literal>DEFAULT</literal> <literal>NULL</literal> ] ) <returnvalue>void</returnvalue> </para> <para> @@ -4730,6 +4730,9 @@ description | Waiting for a newly initialized WAL file to reach durable storage <structname>pg_stat_wal</structname> view or <literal>recovery_prefetch</literal> to reset all the counters shown in the <structname>pg_stat_recovery_prefetch</structname> view. + If <parameter>target</parameter> is <literal>NULL</literal> or + is not specified, all the counters from the views listed above are + reset. </para> <para> This function is restricted to superusers by default, but other users diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index 35d738d576..8079f1cd7f 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -621,6 +621,13 @@ LANGUAGE internal STRICT IMMUTABLE PARALLEL SAFE AS 'unicode_is_normalized'; +CREATE OR REPLACE FUNCTION + pg_stat_reset_shared(target text DEFAULT NULL) +RETURNS void +LANGUAGE INTERNAL +CALLED ON NULL INPUT VOLATILE PARALLEL SAFE +AS 'pg_stat_reset_shared'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c index 1fb8b31863..3a9f9bc4fe 100644 --- a/src/backend/utils/adt/pgstatfuncs.c +++ b/src/backend/utils/adt/pgstatfuncs.c @@ -1685,7 +1685,22 @@ pg_stat_reset(PG_FUNCTION_ARGS) Datum pg_stat_reset_shared(PG_FUNCTION_ARGS) { - char *target = text_to_cstring(PG_GETARG_TEXT_PP(0)); + char *target = NULL; + + if (PG_ARGISNULL(0)) + { + /* Reset all the statistics when nothing is specified */ + pgstat_reset_of_kind(PGSTAT_KIND_ARCHIVER); + pgstat_reset_of_kind(PGSTAT_KIND_BGWRITER); + pgstat_reset_of_kind(PGSTAT_KIND_CHECKPOINTER); + pgstat_reset_of_kind(PGSTAT_KIND_IO); + XLogPrefetchResetStats(); + pgstat_reset_of_kind(PGSTAT_KIND_WAL); + + PG_RETURN_VOID(); + } + + target = text_to_cstring(PG_GETARG_TEXT_PP(0)); if (strcmp(target, "archiver") == 0) pgstat_reset_of_kind(PGSTAT_KIND_ARCHIVER); diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index bee21befda..ff1f392557 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -57,6 +57,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 202310301 +#define CATALOG_VERSION_NO 202311121 #endif diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index f14aed422a..bd0b8873d3 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -5881,8 +5881,9 @@ prorettype => 'void', proargtypes => '', prosrc => 'pg_stat_reset' }, { oid => '3775', descr => 'statistics: reset collected statistics shared across the cluster', - proname => 'pg_stat_reset_shared', provolatile => 'v', prorettype => 'void', - proargtypes => 'text', prosrc => 'pg_stat_reset_shared' }, + proname => 'pg_stat_reset_shared', proisstrict => 'f', provolatile => 'v', + prorettype => 'void', proargtypes => 'text', + prosrc => 'pg_stat_reset_shared' }, { oid => '3776', descr => 'statistics: reset collected statistics for a single table or index in the current database or shared across all databases in the cluster', proname => 'pg_stat_reset_single_table_counters', provolatile => 'v', diff --git a/src/test/regress/expected/stats.out b/src/test/regress/expected/stats.out index 494cef07d3..0694de736a 100644 --- a/src/test/regress/expected/stats.out +++ b/src/test/regress/expected/stats.out @@ -975,38 +975,39 @@ SELECT stats_reset > :'wal_reset_ts'::timestamptz FROM pg_stat_wal; (1 row) SELECT stats_reset AS wal_reset_ts FROM pg_stat_wal \gset --- Test that reset_shared with no specified stats type doesn't reset anything -SELECT pg_stat_reset_shared(NULL); +-- Test that reset_shared with no argument resets all the stats types +-- supported (providing NULL as argument has the same effect). +SELECT pg_stat_reset_shared(); pg_stat_reset_shared ---------------------- (1 row) -SELECT stats_reset = :'archiver_reset_ts'::timestamptz FROM pg_stat_archiver; +SELECT stats_reset > :'archiver_reset_ts'::timestamptz FROM pg_stat_archiver; ?column? ---------- t (1 row) -SELECT stats_reset = :'bgwriter_reset_ts'::timestamptz FROM pg_stat_bgwriter; +SELECT stats_reset > :'bgwriter_reset_ts'::timestamptz FROM pg_stat_bgwriter; ?column? ---------- t (1 row) -SELECT stats_reset = :'checkpointer_reset_ts'::timestamptz FROM pg_stat_checkpointer; +SELECT stats_reset > :'checkpointer_reset_ts'::timestamptz FROM pg_stat_checkpointer; ?column? ---------- t (1 row) -SELECT stats_reset = :'recovery_prefetch_reset_ts'::timestamptz FROM pg_stat_recovery_prefetch; +SELECT stats_reset > :'recovery_prefetch_reset_ts'::timestamptz FROM pg_stat_recovery_prefetch; ?column? ---------- t (1 row) -SELECT stats_reset = :'wal_reset_ts'::timestamptz FROM pg_stat_wal; +SELECT stats_reset > :'wal_reset_ts'::timestamptz FROM pg_stat_wal; ?column? ---------- t diff --git a/src/test/regress/sql/stats.sql b/src/test/regress/sql/stats.sql index 7ae8b8a276..13db45d4dc 100644 --- a/src/test/regress/sql/stats.sql +++ b/src/test/regress/sql/stats.sql @@ -488,13 +488,14 @@ SELECT pg_stat_reset_shared('wal'); SELECT stats_reset > :'wal_reset_ts'::timestamptz FROM pg_stat_wal; SELECT stats_reset AS wal_reset_ts FROM pg_stat_wal \gset --- Test that reset_shared with no specified stats type doesn't reset anything -SELECT pg_stat_reset_shared(NULL); -SELECT stats_reset = :'archiver_reset_ts'::timestamptz FROM pg_stat_archiver; -SELECT stats_reset = :'bgwriter_reset_ts'::timestamptz FROM pg_stat_bgwriter; -SELECT stats_reset = :'checkpointer_reset_ts'::timestamptz FROM pg_stat_checkpointer; -SELECT stats_reset = :'recovery_prefetch_reset_ts'::timestamptz FROM pg_stat_recovery_prefetch; -SELECT stats_reset = :'wal_reset_ts'::timestamptz FROM pg_stat_wal; +-- Test that reset_shared with no argument resets all the stats types +-- supported (providing NULL as argument has the same effect). +SELECT pg_stat_reset_shared(); +SELECT stats_reset > :'archiver_reset_ts'::timestamptz FROM pg_stat_archiver; +SELECT stats_reset > :'bgwriter_reset_ts'::timestamptz FROM pg_stat_bgwriter; +SELECT stats_reset > :'checkpointer_reset_ts'::timestamptz FROM pg_stat_checkpointer; +SELECT stats_reset > :'recovery_prefetch_reset_ts'::timestamptz FROM pg_stat_recovery_prefetch; +SELECT stats_reset > :'wal_reset_ts'::timestamptz FROM pg_stat_wal; -- Test error case for reset_shared with unknown stats type SELECT pg_stat_reset_shared('unknown');