PostgreSQL Source Code git master
injection_stats.c
Go to the documentation of this file.
1/*--------------------------------------------------------------------------
2 *
3 * injection_stats.c
4 * Code for statistics of injection points.
5 *
6 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
8 *
9 * IDENTIFICATION
10 * src/test/modules/injection_points/injection_stats.c
11 *
12 * -------------------------------------------------------------------------
13 */
14
15#include "postgres.h"
16
17#include "fmgr.h"
18
19#include "common/hashfn.h"
20#include "injection_stats.h"
21#include "pgstat.h"
22#include "utils/builtins.h"
24
25/* Structures for statistics of injection points */
26typedef struct PgStat_StatInjEntry
27{
28 PgStat_Counter numcalls; /* number of times point has been run */
30
32{
36
37static bool injection_stats_flush_cb(PgStat_EntryRef *entry_ref, bool nowait);
38
40 .name = "injection_points",
41 .fixed_amount = false, /* Bounded by the number of points */
42 .write_to_file = true,
43
44 /* Injection points are system-wide */
45 .accessed_across_databases = true,
46
47 .shared_size = sizeof(PgStatShared_InjectionPoint),
48 .shared_data_off = offsetof(PgStatShared_InjectionPoint, stats),
49 .shared_data_len = sizeof(((PgStatShared_InjectionPoint *) 0)->stats),
50 .pending_size = sizeof(PgStat_StatInjEntry),
51 .flush_pending_cb = injection_stats_flush_cb,
52};
53
54/*
55 * Compute stats entry idx from point name with an 8-byte hash.
56 */
57#define PGSTAT_INJ_IDX(name) hash_bytes_extended((const unsigned char *) name, strlen(name), 0)
58
59/*
60 * Kind ID reserved for statistics of injection points.
61 */
62#define PGSTAT_KIND_INJECTION 129
63
64/* Track if stats are loaded */
65static bool inj_stats_loaded = false;
66
67/*
68 * Callback for stats handling
69 */
70static bool
72{
73 PgStat_StatInjEntry *localent;
75
76 localent = (PgStat_StatInjEntry *) entry_ref->pending;
77 shfuncent = (PgStatShared_InjectionPoint *) entry_ref->shared_stats;
78
79 if (!pgstat_lock_entry(entry_ref, nowait))
80 return false;
81
82 shfuncent->stats.numcalls += localent->numcalls;
83
84 pgstat_unlock_entry(entry_ref);
85
86 return true;
87}
88
89/*
90 * Support function for the SQL-callable pgstat* functions. Returns
91 * a pointer to the injection point statistics struct.
92 */
95{
96 PgStat_StatInjEntry *entry = NULL;
97
99 return NULL;
100
101 /* Compile the lookup key as a hash of the point name */
105 return entry;
106}
107
108/*
109 * Workhorse to do the registration work, called in _PG_init().
110 */
111void
113{
115
116 /* mark stats as loaded */
117 inj_stats_loaded = true;
118}
119
120/*
121 * Report injection point creation.
122 */
123void
125{
126 PgStat_EntryRef *entry_ref;
128
129 /* leave if disabled */
131 return;
132
134 PGSTAT_INJ_IDX(name), NULL);
135
136 shstatent = (PgStatShared_InjectionPoint *) entry_ref->shared_stats;
137
138 /* initialize shared memory data */
139 memset(&shstatent->stats, 0, sizeof(shstatent->stats));
140}
141
142/*
143 * Report injection point drop.
144 */
145void
147{
148 /* leave if disabled */
150 return;
151
155}
156
157/*
158 * Report statistics for injection point.
159 *
160 * This is simple because the set of stats to report currently is simple:
161 * track the number of times a point has been run.
162 */
163void
165{
166 PgStat_EntryRef *entry_ref;
168 PgStat_StatInjEntry *statent;
169
170 /* leave if disabled */
172 return;
173
175 PGSTAT_INJ_IDX(name), NULL);
176
177 shstatent = (PgStatShared_InjectionPoint *) entry_ref->shared_stats;
178 statent = &shstatent->stats;
179
180 /* Update the injection point statistics */
181 statent->numcalls++;
182}
183
184/*
185 * SQL function returning the number of times an injection point
186 * has been called.
187 */
189Datum
191{
194
195 if (entry == NULL)
197
199}
200
201/* Only used by injection_points_stats_drop() */
202static bool
204{
205 return entry->key.kind == PGSTAT_KIND_INJECTION;
206}
207
208/*
209 * SQL function that drops all injection point statistics.
210 */
212Datum
214{
216
218}
#define PG_RETURN_VOID()
Definition: fmgr.h:349
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
#define PG_RETURN_INT64(x)
Definition: fmgr.h:368
#define PG_RETURN_NULL()
Definition: fmgr.h:345
#define PG_FUNCTION_ARGS
Definition: fmgr.h:193
bool inj_stats_enabled
void pgstat_report_inj(const char *name)
void pgstat_register_inj(void)
static bool inj_stats_loaded
#define PGSTAT_INJ_IDX(name)
void pgstat_create_inj(const char *name)
struct PgStat_StatInjEntry PgStat_StatInjEntry
void pgstat_drop_inj(const char *name)
#define PGSTAT_KIND_INJECTION
PG_FUNCTION_INFO_V1(injection_points_stats_numcalls)
static bool match_inj_entries(PgStatShared_HashEntry *entry, Datum match_data)
static bool injection_stats_flush_cb(PgStat_EntryRef *entry_ref, bool nowait)
static const PgStat_KindInfo injection_stats
struct PgStatShared_InjectionPoint PgStatShared_InjectionPoint
Datum injection_points_stats_drop(PG_FUNCTION_ARGS)
Datum injection_points_stats_numcalls(PG_FUNCTION_ARGS)
static PgStat_StatInjEntry * pgstat_fetch_stat_injentry(const char *name)
PgStat_EntryRef * pgstat_prep_pending_entry(PgStat_Kind kind, Oid dboid, uint64 objid, bool *created_entry)
Definition: pgstat.c:1283
void * pgstat_fetch_entry(PgStat_Kind kind, Oid dboid, uint64 objid)
Definition: pgstat.c:949
void pgstat_register_kind(PgStat_Kind kind, const PgStat_KindInfo *kind_info)
Definition: pgstat.c:1481
int64 PgStat_Counter
Definition: pgstat.h:65
void pgstat_request_entry_refs_gc(void)
Definition: pgstat_shmem.c:700
bool pgstat_drop_entry(PgStat_Kind kind, Oid dboid, uint64 objid)
Definition: pgstat_shmem.c:953
void pgstat_drop_matching_entries(bool(*do_drop)(PgStatShared_HashEntry *, Datum), Datum match_data)
void pgstat_unlock_entry(PgStat_EntryRef *entry_ref)
Definition: pgstat_shmem.c:675
bool pgstat_lock_entry(PgStat_EntryRef *entry_ref, bool nowait)
Definition: pgstat_shmem.c:647
uintptr_t Datum
Definition: postgres.h:69
#define InvalidOid
Definition: postgres_ext.h:37
PgStat_StatInjEntry stats
PgStatShared_Common header
PgStatShared_Common * shared_stats
PgStat_Kind kind
const char *const name
PgStat_Counter numcalls
char * text_to_cstring(const text *t)
Definition: varlena.c:225
const char * name