1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-21 00:42:43 +03:00
Files
postgres/src/test/modules/injection_points/injection_stats_fixed.c
Michael Paquier c06e71d1ac Add write_to_file to PgStat_KindInfo for pgstats kinds
This new field controls if entries of a stats kind should be written or
not to the on-disk pgstats file when shutting down an instance.  This
affects both fixed and variable-numbered kinds.

This is useful for custom statistics by itself, and a patch is under
discussion to add a new builtin stats kind where the write of the stats
is not necessary.  All the built-in stats kinds, as well as the two
custom stats kinds in the test module injection_points, set this flag to
"true" for now, so as stats entries are written to the on-disk pgstats
file.

Author: Bertrand Drouvot
Reviewed-by: Nazir Bilal Yavuz
Discussion: https://postgr.es/m/Zz7T47nHwYgeYwOe@ip-10-97-1-34.eu-west-3.compute.internal
2024-11-22 10:12:26 +09:00

210 lines
6.2 KiB
C

/*--------------------------------------------------------------------------
*
* 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 */
PgStat_Counter numcached; /* number of points cached */
PgStat_Counter numloaded; /* number of points loaded */
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,
.write_to_file = 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);
FIXED_COMP(numcached);
FIXED_COMP(numloaded);
#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,
uint32 numcached,
uint32 numloaded)
{
PgStatShared_InjectionPointFixed *stats_shmem;
/* leave if disabled */
if (!inj_fixed_loaded || !inj_stats_enabled)
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;
stats_shmem->stats.numcached += numcached;
stats_shmem->stats.numloaded += numloaded;
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[5] = {0};
bool nulls[5] = {0};
PgStat_StatInjFixedEntry *stats;
if (!inj_fixed_loaded || !inj_stats_enabled)
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(5);
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "numattach",
INT8OID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 2, "numdetach",
INT8OID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 3, "numrun",
INT8OID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 4, "numcached",
INT8OID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 5, "numloaded",
INT8OID, -1, 0);
BlessTupleDesc(tupdesc);
values[0] = Int64GetDatum(stats->numattach);
values[1] = Int64GetDatum(stats->numdetach);
values[2] = Int64GetDatum(stats->numrun);
values[3] = Int64GetDatum(stats->numcached);
values[4] = Int64GetDatum(stats->numloaded);
nulls[0] = false;
nulls[1] = false;
nulls[2] = false;
nulls[3] = false;
nulls[4] = false;
/* Returns the record as Datum */
PG_RETURN_DATUM(HeapTupleGetDatum(heap_form_tuple(tupdesc, values, nulls)));
}