mirror of
https://github.com/postgres/postgres.git
synced 2025-05-01 01:04:50 +03:00
injection_points: Add some fixed-numbered statistics
Like 75534436a477, this acts mainly as a template to show what can be achieved with fixed-numbered stats (like WAL, bgwriter, etc.) with the pluggable cumulative statistics APIs introduced in 7949d9594582. Fixed-numbered stats are defined in their own file, named injection_stats_fixed.c, separated entirely from the variable-numbered case in injection_stats.c. This is mainly for clarity as having both examples in the same file would be confusing. Note that this commit uses the helper routines added in 2eff9e678d35. The stats stored track globally the number of times injection points have been attached, detached or run. Two more fields should be added later for the number of times a point has been cached or loaded, but what's here is enough as a template. More TAP tests are added, providing coverage for fixed-numbered custom stats. Author: Michael Paquier Reviewed-by: Dmitry Dolgov, Bertrand Drouvot Discussion: https://postgr.es/m/Zmqm9j5EO0I4W8dx@paquier.xyz
This commit is contained in:
parent
75534436a4
commit
f68cd847fa
@ -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"
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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
|
||||
|
192
src/test/modules/injection_points/injection_stats_fixed.c
Normal file
192
src/test/modules/injection_points/injection_stats_fixed.c
Normal file
@ -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)));
|
||||
}
|
@ -7,6 +7,7 @@ endif
|
||||
injection_points_sources = files(
|
||||
'injection_points.c',
|
||||
'injection_stats.c',
|
||||
'injection_stats_fixed.c',
|
||||
)
|
||||
|
||||
if host_system == 'windows'
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user