aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/test/modules/injection_points/Makefile3
-rw-r--r--src/test/modules/injection_points/injection_points--1.0.sql11
-rw-r--r--src/test/modules/injection_points/injection_points.c4
-rw-r--r--src/test/modules/injection_points/injection_stats.h7
-rw-r--r--src/test/modules/injection_points/injection_stats_fixed.c192
-rw-r--r--src/test/modules/injection_points/meson.build1
-rw-r--r--src/test/modules/injection_points/t/001_stats.pl11
-rw-r--r--src/tools/pgindent/typedefs.list2
8 files changed, 229 insertions, 2 deletions
diff --git a/src/test/modules/injection_points/Makefile b/src/test/modules/injection_points/Makefile
index 7b9cd12a2a9..ed28cd13a8b 100644
--- a/src/test/modules/injection_points/Makefile
+++ b/src/test/modules/injection_points/Makefile
@@ -4,7 +4,8 @@ MODULE_big = injection_points
OBJS = \
$(WIN32RES) \
injection_points.o \
- injection_stats.o
+ injection_stats.o \
+ injection_stats_fixed.o
EXTENSION = injection_points
DATA = injection_points--1.0.sql
PGFILEDESC = "injection_points - facility for injection points"
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 b98d5718890..1b2a4938a95 100644
--- a/src/test/modules/injection_points/injection_points--1.0.sql
+++ b/src/test/modules/injection_points/injection_points--1.0.sql
@@ -84,3 +84,14 @@ CREATE FUNCTION injection_points_stats_numcalls(IN point_name TEXT)
RETURNS bigint
AS 'MODULE_PATHNAME', 'injection_points_stats_numcalls'
LANGUAGE C STRICT;
+
+--
+-- injection_points_stats_fixed()
+--
+-- Reports fixed-numbered statistics for injection points.
+CREATE FUNCTION injection_points_stats_fixed(OUT numattach int8,
+ OUT numdetach int8,
+ OUT numrun int8)
+RETURNS record
+AS 'MODULE_PATHNAME', 'injection_points_stats_fixed'
+LANGUAGE C STRICT;
diff --git a/src/test/modules/injection_points/injection_points.c b/src/test/modules/injection_points/injection_points.c
index acec4e95b05..dc02be1bbf6 100644
--- a/src/test/modules/injection_points/injection_points.c
+++ b/src/test/modules/injection_points/injection_points.c
@@ -297,6 +297,7 @@ injection_points_attach(PG_FUNCTION_ARGS)
condition.pid = MyProcPid;
}
+ pgstat_report_inj_fixed(1, 0, 0);
InjectionPointAttach(name, "injection_points", function, &condition,
sizeof(InjectionPointCondition));
@@ -342,6 +343,7 @@ injection_points_run(PG_FUNCTION_ARGS)
{
char *name = text_to_cstring(PG_GETARG_TEXT_PP(0));
+ pgstat_report_inj_fixed(0, 0, 1);
INJECTION_POINT(name);
PG_RETURN_VOID();
@@ -432,6 +434,7 @@ injection_points_detach(PG_FUNCTION_ARGS)
{
char *name = text_to_cstring(PG_GETARG_TEXT_PP(0));
+ pgstat_report_inj_fixed(0, 1, 0);
if (!InjectionPointDetach(name))
elog(ERROR, "could not detach injection point \"%s\"", name);
@@ -459,4 +462,5 @@ _PG_init(void)
return;
pgstat_register_inj();
+ pgstat_register_inj_fixed();
}
diff --git a/src/test/modules/injection_points/injection_stats.h b/src/test/modules/injection_points/injection_stats.h
index 3e997054834..d519f29f832 100644
--- a/src/test/modules/injection_points/injection_stats.h
+++ b/src/test/modules/injection_points/injection_stats.h
@@ -15,9 +15,16 @@
#ifndef INJECTION_STATS
#define INJECTION_STATS
+/* injection_stats.c */
extern void pgstat_register_inj(void);
extern void pgstat_create_inj(const char *name);
extern void pgstat_drop_inj(const char *name);
extern void pgstat_report_inj(const char *name);
+/* injection_stats_fixed.c */
+extern void pgstat_register_inj_fixed(void);
+extern void pgstat_report_inj_fixed(uint32 numattach,
+ uint32 numdetach,
+ uint32 numrun);
+
#endif
diff --git a/src/test/modules/injection_points/injection_stats_fixed.c b/src/test/modules/injection_points/injection_stats_fixed.c
new file mode 100644
index 00000000000..72a5f9decb9
--- /dev/null
+++ b/src/test/modules/injection_points/injection_stats_fixed.c
@@ -0,0 +1,192 @@
+/*--------------------------------------------------------------------------
+ *
+ * injection_stats_fixed.c
+ * Code for fixed-numbered statistics of injection points.
+ *
+ * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * IDENTIFICATION
+ * src/test/modules/injection_points/injection_stats_fixed.c
+ *
+ * -------------------------------------------------------------------------
+ */
+
+#include "postgres.h"
+
+#include "fmgr.h"
+
+#include "common/hashfn.h"
+#include "funcapi.h"
+#include "injection_stats.h"
+#include "pgstat.h"
+#include "utils/builtins.h"
+#include "utils/pgstat_internal.h"
+
+/* Structures for statistics of injection points, fixed-size */
+typedef struct PgStat_StatInjFixedEntry
+{
+ PgStat_Counter numattach; /* number of points attached */
+ PgStat_Counter numdetach; /* number of points detached */
+ PgStat_Counter numrun; /* number of points run */
+ TimestampTz stat_reset_timestamp;
+} PgStat_StatInjFixedEntry;
+
+typedef struct PgStatShared_InjectionPointFixed
+{
+ LWLock lock; /* protects all the counters */
+ uint32 changecount;
+ PgStat_StatInjFixedEntry stats;
+ PgStat_StatInjFixedEntry reset_offset;
+} PgStatShared_InjectionPointFixed;
+
+/* Callbacks for fixed-numbered stats */
+static void injection_stats_fixed_init_shmem_cb(void *stats);
+static void injection_stats_fixed_reset_all_cb(TimestampTz ts);
+static void injection_stats_fixed_snapshot_cb(void);
+
+static const PgStat_KindInfo injection_stats_fixed = {
+ .name = "injection_points_fixed",
+ .fixed_amount = true,
+
+ .shared_size = sizeof(PgStat_StatInjFixedEntry),
+ .shared_data_off = offsetof(PgStatShared_InjectionPointFixed, stats),
+ .shared_data_len = sizeof(((PgStatShared_InjectionPointFixed *) 0)->stats),
+
+ .init_shmem_cb = injection_stats_fixed_init_shmem_cb,
+ .reset_all_cb = injection_stats_fixed_reset_all_cb,
+ .snapshot_cb = injection_stats_fixed_snapshot_cb,
+};
+
+/*
+ * Kind ID reserved for statistics of injection points.
+ */
+#define PGSTAT_KIND_INJECTION_FIXED 130
+
+/* Track if fixed-numbered stats are loaded */
+static bool inj_fixed_loaded = false;
+
+static void
+injection_stats_fixed_init_shmem_cb(void *stats)
+{
+ PgStatShared_InjectionPointFixed *stats_shmem =
+ (PgStatShared_InjectionPointFixed *) stats;
+
+ LWLockInitialize(&stats_shmem->lock, LWTRANCHE_PGSTATS_DATA);
+}
+
+static void
+injection_stats_fixed_reset_all_cb(TimestampTz ts)
+{
+ PgStatShared_InjectionPointFixed *stats_shmem =
+ pgstat_get_custom_shmem_data(PGSTAT_KIND_INJECTION_FIXED);
+
+ LWLockAcquire(&stats_shmem->lock, LW_EXCLUSIVE);
+ pgstat_copy_changecounted_stats(&stats_shmem->reset_offset,
+ &stats_shmem->stats,
+ sizeof(stats_shmem->stats),
+ &stats_shmem->changecount);
+ stats_shmem->stats.stat_reset_timestamp = ts;
+ LWLockRelease(&stats_shmem->lock);
+}
+
+static void
+injection_stats_fixed_snapshot_cb(void)
+{
+ PgStatShared_InjectionPointFixed *stats_shmem =
+ pgstat_get_custom_shmem_data(PGSTAT_KIND_INJECTION_FIXED);
+ PgStat_StatInjFixedEntry *stat_snap =
+ pgstat_get_custom_snapshot_data(PGSTAT_KIND_INJECTION_FIXED);
+ PgStat_StatInjFixedEntry *reset_offset = &stats_shmem->reset_offset;
+ PgStat_StatInjFixedEntry reset;
+
+ pgstat_copy_changecounted_stats(stat_snap,
+ &stats_shmem->stats,
+ sizeof(stats_shmem->stats),
+ &stats_shmem->changecount);
+
+ LWLockAcquire(&stats_shmem->lock, LW_SHARED);
+ memcpy(&reset, reset_offset, sizeof(stats_shmem->stats));
+ LWLockRelease(&stats_shmem->lock);
+
+ /* compensate by reset offsets */
+#define FIXED_COMP(fld) stat_snap->fld -= reset.fld;
+ FIXED_COMP(numattach);
+ FIXED_COMP(numdetach);
+ FIXED_COMP(numrun);
+#undef FIXED_COMP
+}
+
+/*
+ * Workhorse to do the registration work, called in _PG_init().
+ */
+void
+pgstat_register_inj_fixed(void)
+{
+ pgstat_register_kind(PGSTAT_KIND_INJECTION_FIXED, &injection_stats_fixed);
+
+ /* mark stats as loaded */
+ inj_fixed_loaded = true;
+}
+
+/*
+ * Report fixed number of statistics for an injection point.
+ */
+void
+pgstat_report_inj_fixed(uint32 numattach,
+ uint32 numdetach,
+ uint32 numrun)
+{
+ PgStatShared_InjectionPointFixed *stats_shmem;
+
+ /* leave if disabled */
+ if (!inj_fixed_loaded)
+ return;
+
+ stats_shmem = pgstat_get_custom_shmem_data(PGSTAT_KIND_INJECTION_FIXED);
+
+ pgstat_begin_changecount_write(&stats_shmem->changecount);
+ stats_shmem->stats.numattach += numattach;
+ stats_shmem->stats.numdetach += numdetach;
+ stats_shmem->stats.numrun += numrun;
+ pgstat_end_changecount_write(&stats_shmem->changecount);
+}
+
+/*
+ * SQL function returning fixed-numbered statistics for injection points.
+ */
+PG_FUNCTION_INFO_V1(injection_points_stats_fixed);
+Datum
+injection_points_stats_fixed(PG_FUNCTION_ARGS)
+{
+ TupleDesc tupdesc;
+ Datum values[3] = {0};
+ bool nulls[3] = {0};
+ PgStat_StatInjFixedEntry *stats;
+
+ if (!inj_fixed_loaded)
+ PG_RETURN_NULL();
+
+ pgstat_snapshot_fixed(PGSTAT_KIND_INJECTION_FIXED);
+ stats = pgstat_get_custom_snapshot_data(PGSTAT_KIND_INJECTION_FIXED);
+
+ /* Initialise attributes information in the tuple descriptor */
+ tupdesc = CreateTemplateTupleDesc(3);
+ TupleDescInitEntry(tupdesc, (AttrNumber) 1, "numattach",
+ INT8OID, -1, 0);
+ TupleDescInitEntry(tupdesc, (AttrNumber) 2, "numdetach",
+ INT8OID, -1, 0);
+ TupleDescInitEntry(tupdesc, (AttrNumber) 3, "numrun",
+ INT8OID, -1, 0);
+ BlessTupleDesc(tupdesc);
+
+ values[0] = Int64GetDatum(stats->numattach);
+ values[1] = Int64GetDatum(stats->numdetach);
+ values[2] = Int64GetDatum(stats->numrun);
+ nulls[0] = false;
+ nulls[1] = false;
+ nulls[2] = false;
+
+ /* Returns the record as Datum */
+ PG_RETURN_DATUM(HeapTupleGetDatum(heap_form_tuple(tupdesc, values, nulls)));
+}
diff --git a/src/test/modules/injection_points/meson.build b/src/test/modules/injection_points/meson.build
index a52fe5121e5..c9e357f6441 100644
--- a/src/test/modules/injection_points/meson.build
+++ b/src/test/modules/injection_points/meson.build
@@ -7,6 +7,7 @@ endif
injection_points_sources = files(
'injection_points.c',
'injection_stats.c',
+ 'injection_stats_fixed.c',
)
if host_system == 'windows'
diff --git a/src/test/modules/injection_points/t/001_stats.pl b/src/test/modules/injection_points/t/001_stats.pl
index fff805b46a9..7897691f954 100644
--- a/src/test/modules/injection_points/t/001_stats.pl
+++ b/src/test/modules/injection_points/t/001_stats.pl
@@ -33,18 +33,27 @@ $node->safe_psql('postgres', "SELECT injection_points_run('stats-notice');");
my $numcalls = $node->safe_psql('postgres',
"SELECT injection_points_stats_numcalls('stats-notice');");
is($numcalls, '2', 'number of stats calls');
+my $fixedstats = $node->safe_psql('postgres',
+ "SELECT * FROM injection_points_stats_fixed();");
+is($fixedstats, '1|0|2', 'number of fixed stats');
# Restart the node cleanly, stats should still be around.
$node->restart;
$numcalls = $node->safe_psql('postgres',
"SELECT injection_points_stats_numcalls('stats-notice');");
is($numcalls, '2', 'number of stats after clean restart');
+$fixedstats = $node->safe_psql('postgres',
+ "SELECT * FROM injection_points_stats_fixed();");
+is($fixedstats, '1|0|2', 'number of fixed stats after clean restart');
# On crash the stats are gone.
$node->stop('immediate');
$node->start;
$numcalls = $node->safe_psql('postgres',
"SELECT injection_points_stats_numcalls('stats-notice');");
-is($numcalls, '', 'number of stats after clean restart');
+is($numcalls, '', 'number of stats after crash');
+$fixedstats = $node->safe_psql('postgres',
+ "SELECT * FROM injection_points_stats_fixed();");
+is($fixedstats, '0|0|0', 'number of fixed stats after crash');
done_testing();
diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list
index 6cabdb02d68..6e6b7c27118 100644
--- a/src/tools/pgindent/typedefs.list
+++ b/src/tools/pgindent/typedefs.list
@@ -2120,6 +2120,7 @@ PgStatShared_Database
PgStatShared_Function
PgStatShared_HashEntry
PgStatShared_InjectionPoint
+PgStatShared_InjectionPointFixed
PgStatShared_IO
PgStatShared_Relation
PgStatShared_ReplSlot
@@ -2152,6 +2153,7 @@ PgStat_SnapshotEntry
PgStat_StatDBEntry
PgStat_StatFuncEntry
PgStat_StatInjEntry
+PgStat_StatInjFixedEntry
PgStat_StatReplSlotEntry
PgStat_StatSubEntry
PgStat_StatTabEntry