/*--------------------------------------------------------------------------
*
* injection_stats . c
* Code for statistics of injection points .
*
* Portions Copyright ( c ) 1996 - 2025 , PostgreSQL Global Development Group
* Portions Copyright ( c ) 1994 , Regents of the University of California
*
* IDENTIFICATION
* src / test / modules / injection_points / injection_stats . c
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
#include "postgres.h"
#include "fmgr.h"
#include "common/hashfn.h"
#include "injection_stats.h"
#include "pgstat.h"
#include "utils/builtins.h"
#include "utils/pgstat_internal.h"
/* Structures for statistics of injection points */
typedef struct PgStat_StatInjEntry
{
PgStat_Counter numcalls; /* number of times point has been run */
} PgStat_StatInjEntry;
typedef struct PgStatShared_InjectionPoint
{
PgStatShared_Common header;
PgStat_StatInjEntry stats;
} PgStatShared_InjectionPoint;
static bool injection_stats_flush_cb(PgStat_EntryRef *entry_ref, bool nowait);
static const PgStat_KindInfo injection_stats = {
.name = "injection_points" ,
.fixed_amount = false , /* Bounded by the number of points */
.write_to_file = true ,
/* Injection points are system-wide */
.accessed_across_databases = true ,
.shared_size = sizeof (PgStatShared_InjectionPoint),
.shared_data_off = offsetof(PgStatShared_InjectionPoint, stats),
.shared_data_len = sizeof (((PgStatShared_InjectionPoint *) 0 )->stats),
.pending_size = sizeof (PgStat_StatInjEntry),
.flush_pending_cb = injection_stats_flush_cb,
};
/*
* Compute stats entry idx from point name with an 8 - byte hash .
*/
#define PGSTAT_INJ_IDX(name) hash_bytes_extended((const unsigned char *) name, strlen(name), 0 )
/*
* Kind ID reserved for statistics of injection points .
*/
#define PGSTAT_KIND_INJECTION 25
/* Track if stats are loaded */
static bool inj_stats_loaded = false ;
/*
* Callback for stats handling
*/
static bool
injection_stats_flush_cb(PgStat_EntryRef *entry_ref, bool nowait)
{
PgStat_StatInjEntry *localent;
PgStatShared_InjectionPoint *shfuncent;
localent = (PgStat_StatInjEntry *) entry_ref->pending;
shfuncent = (PgStatShared_InjectionPoint *) entry_ref->shared_stats;
if (!pgstat_lock_entry(entry_ref, nowait))
return false ;
shfuncent->stats.numcalls += localent->numcalls;
pgstat_unlock_entry(entry_ref);
return true ;
}
/*
* Support function for the SQL - callable pgstat * functions . Returns
* a pointer to the injection point statistics struct .
*/
static PgStat_StatInjEntry *
pgstat_fetch_stat_injentry(const char *name)
{
PgStat_StatInjEntry *entry = NULL;
if (!inj_stats_loaded || !inj_stats_enabled)
return NULL;
/* Compile the lookup key as a hash of the point name */
entry = (PgStat_StatInjEntry *) pgstat_fetch_entry(PGSTAT_KIND_INJECTION,
InvalidOid,
PGSTAT_INJ_IDX(name));
return entry;
}
/*
* Workhorse to do the registration work , called in _ PG_init ( ) .
*/
void
pgstat_register_inj(void )
{
pgstat_register_kind(PGSTAT_KIND_INJECTION, &injection_stats);
/* mark stats as loaded */
inj_stats_loaded = true ;
}
/*
* Report injection point creation .
*/
void
pgstat_create_inj(const char *name)
{
PgStat_EntryRef *entry_ref;
PgStatShared_InjectionPoint *shstatent;
/* leave if disabled */
if (!inj_stats_loaded || !inj_stats_enabled)
return ;
entry_ref = pgstat_prep_pending_entry(PGSTAT_KIND_INJECTION, InvalidOid,
PGSTAT_INJ_IDX(name), NULL);
shstatent = (PgStatShared_InjectionPoint *) entry_ref->shared_stats;
/* initialize shared memory data */
memset(&shstatent->stats, 0 , sizeof (shstatent->stats));
}
/*
* Report injection point drop .
*/
void
pgstat_drop_inj(const char *name)
{
/* leave if disabled */
if (!inj_stats_loaded || !inj_stats_enabled)
return ;
if (!pgstat_drop_entry(PGSTAT_KIND_INJECTION, InvalidOid,
PGSTAT_INJ_IDX(name)))
pgstat_request_entry_refs_gc();
}
/*
* Report statistics for injection point .
*
* This is simple because the set of stats to report currently is simple :
* track the number of times a point has been run .
*/
void
pgstat_report_inj(const char *name)
{
PgStat_EntryRef *entry_ref;
PgStat_StatInjEntry *pending;
/* leave if disabled */
if (!inj_stats_loaded || !inj_stats_enabled)
return ;
entry_ref = pgstat_prep_pending_entry(PGSTAT_KIND_INJECTION, InvalidOid,
PGSTAT_INJ_IDX(name), NULL);
pending = (PgStat_StatInjEntry *) entry_ref->pending;
/* Update the injection point pending statistics */
pending->numcalls++;
}
/*
* SQL function returning the number of times an injection point
* has been called .
*/
PG_FUNCTION_INFO_V1(injection_points_stats_numcalls);
Datum
injection_points_stats_numcalls(PG_FUNCTION_ARGS)
{
char *name = text_to_cstring(PG_GETARG_TEXT_PP(0 ));
PgStat_StatInjEntry *entry = pgstat_fetch_stat_injentry(name);
if (entry == NULL)
PG_RETURN_NULL();
PG_RETURN_INT64(entry->numcalls);
}
/* Only used by injection_points_stats_drop() */
static bool
match_inj_entries(PgStatShared_HashEntry *entry, Datum match_data)
{
return entry->key.kind == PGSTAT_KIND_INJECTION;
}
/*
* SQL function that drops all injection point statistics .
*/
PG_FUNCTION_INFO_V1(injection_points_stats_drop);
Datum
injection_points_stats_drop(PG_FUNCTION_ARGS)
{
pgstat_drop_matching_entries(match_inj_entries, 0 );
PG_RETURN_VOID();
}
Messung V0.5 in Prozent C=88 H=98 G=93
¤ Dauer der Verarbeitung: 0.30 Sekunden
(vorverarbeitet am 2026-08-08)
¤
*© Formatika GbR, Deutschland