v2-0002-Cumulative-statistics-Add-pgstat_drop_entries_of_.patch
application/x-patch
Filename: v2-0002-Cumulative-statistics-Add-pgstat_drop_entries_of_.patch
Type: application/x-patch
Part: 2
From c3272a0012d897eaadc72f50e3e336e76671f92e Mon Sep 17 00:00:00 2001
From: Lukas Fittl <lukas@fittl.com>
Date: Thu, 2 Jan 2025 10:46:30 -0800
Subject: [PATCH v2 2/4] Cumulative statistics: Add pgstat_drop_entries_of_kind
helper
This allows users of the cumulative statistics systems to drop all
entries for a given kind, similar to how pgstat_reset_entries_of_kind
allows resetting all entries for a given statistics kind.
Add an example use of pgstat_drop_entries_of_kind in the injection
points module by adding a injection_points_stats_reset function.
---
src/backend/utils/activity/pgstat_shmem.c | 33 +++++++++++++++++++
src/include/utils/pgstat_internal.h | 1 +
.../injection_points--1.0.sql | 10 ++++++
.../injection_points/injection_stats.c | 12 +++++++
.../modules/injection_points/t/001_stats.pl | 13 ++++++++
5 files changed, 69 insertions(+)
diff --git a/src/backend/utils/activity/pgstat_shmem.c b/src/backend/utils/activity/pgstat_shmem.c
index 342586397d..7b63bb3903 100644
--- a/src/backend/utils/activity/pgstat_shmem.c
+++ b/src/backend/utils/activity/pgstat_shmem.c
@@ -1015,6 +1015,39 @@ pgstat_drop_all_entries(void)
pgstat_request_entry_refs_gc();
}
+void
+pgstat_drop_entries_of_kind(PgStat_Kind kind)
+{
+ dshash_seq_status hstat;
+ PgStatShared_HashEntry *ps;
+ uint64 not_freed_count = 0;
+
+ dshash_seq_init(&hstat, pgStatLocal.shared_hash, true);
+ while ((ps = dshash_seq_next(&hstat)) != NULL)
+ {
+ if (ps->dropped || ps->key.kind != kind)
+ continue;
+
+ /* delete local reference */
+ if (pgStatEntryRefHash)
+ {
+ PgStat_EntryRefHashEntry *lohashent =
+ pgstat_entry_ref_hash_lookup(pgStatEntryRefHash, ps->key);
+
+ if (lohashent)
+ pgstat_release_entry_ref(lohashent->key, lohashent->entry_ref,
+ true);
+ }
+
+ if (!pgstat_drop_entry_internal(ps, &hstat))
+ not_freed_count++;
+ }
+ dshash_seq_term(&hstat);
+
+ if (not_freed_count > 0)
+ pgstat_request_entry_refs_gc();
+}
+
static void
shared_stat_reset_contents(PgStat_Kind kind, PgStatShared_Common *header,
TimestampTz ts)
diff --git a/src/include/utils/pgstat_internal.h b/src/include/utils/pgstat_internal.h
index a3d39d2b72..fe3e891257 100644
--- a/src/include/utils/pgstat_internal.h
+++ b/src/include/utils/pgstat_internal.h
@@ -718,6 +718,7 @@ extern bool pgstat_lock_entry_shared(PgStat_EntryRef *entry_ref, bool nowait);
extern void pgstat_unlock_entry(PgStat_EntryRef *entry_ref);
extern bool pgstat_drop_entry(PgStat_Kind kind, Oid dboid, uint64 objid);
extern void pgstat_drop_all_entries(void);
+extern void pgstat_drop_entries_of_kind(PgStat_Kind kind);
extern PgStat_EntryRef *pgstat_get_entry_ref_locked(PgStat_Kind kind, Oid dboid, uint64 objid,
bool nowait);
extern void pgstat_reset_entry(PgStat_Kind kind, Oid dboid, uint64 objid, TimestampTz ts);
diff --git a/src/test/modules/injection_points/injection_points--1.0.sql b/src/test/modules/injection_points/injection_points--1.0.sql
index 6c81d55e0d..1d8a085c81 100644
--- a/src/test/modules/injection_points/injection_points--1.0.sql
+++ b/src/test/modules/injection_points/injection_points--1.0.sql
@@ -85,6 +85,16 @@ RETURNS bigint
AS 'MODULE_PATHNAME', 'injection_points_stats_numcalls'
LANGUAGE C STRICT;
+--
+-- injection_points_stats_reset()
+--
+-- Reports statistics, if any, related to the given injection point.
+--
+CREATE FUNCTION injection_points_stats_reset()
+RETURNS void
+AS 'MODULE_PATHNAME', 'injection_points_stats_reset'
+LANGUAGE C STRICT;
+
--
-- injection_points_stats_fixed()
--
diff --git a/src/test/modules/injection_points/injection_stats.c b/src/test/modules/injection_points/injection_stats.c
index 5db62bca66..99468d4b7e 100644
--- a/src/test/modules/injection_points/injection_stats.c
+++ b/src/test/modules/injection_points/injection_stats.c
@@ -197,3 +197,15 @@ injection_points_stats_numcalls(PG_FUNCTION_ARGS)
PG_RETURN_INT64(entry->numcalls);
}
+
+/*
+ * SQL function that resets injection point statistics.
+ */
+PG_FUNCTION_INFO_V1(injection_points_stats_reset);
+Datum
+injection_points_stats_reset(PG_FUNCTION_ARGS)
+{
+ pgstat_drop_entries_of_kind(PGSTAT_KIND_INJECTION);
+
+ PG_RETURN_VOID();
+}
diff --git a/src/test/modules/injection_points/t/001_stats.pl b/src/test/modules/injection_points/t/001_stats.pl
index d4539fe872..dc83367958 100644
--- a/src/test/modules/injection_points/t/001_stats.pl
+++ b/src/test/modules/injection_points/t/001_stats.pl
@@ -69,6 +69,19 @@ $fixedstats = $node->safe_psql('postgres',
"SELECT * FROM injection_points_stats_fixed();");
is($fixedstats, '0|0|0|0|0', 'fixed stats after crash');
+# On reset the stats are gone
+$node->safe_psql('postgres',
+ "SELECT injection_points_attach('stats-notice', 'notice');");
+$node->safe_psql('postgres', "SELECT injection_points_run('stats-notice');");
+$node->safe_psql('postgres', "SELECT injection_points_run('stats-notice');");
+$numcalls = $node->safe_psql('postgres',
+ "SELECT injection_points_stats_numcalls('stats-notice');");
+is($numcalls, '2', 'number of stats calls');
+$node->safe_psql('postgres', "SELECT injection_points_stats_reset();");
+$numcalls = $node->safe_psql('postgres',
+ "SELECT injection_points_stats_numcalls('stats-notice');");
+is($numcalls, '', 'number of stats after reset');
+
# Stop the server, disable the module, then restart. The server
# should be able to come up.
$node->stop;
--
2.47.1