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-2024, 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"
23 #include "utils/pgstat_internal.h"
24 
25 /* Structures for statistics of injection points */
26 typedef struct PgStat_StatInjEntry
27 {
28  PgStat_Counter numcalls; /* number of times point has been run */
30 
32 {
36 
37 static 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 */
65 static bool inj_stats_loaded = false;
66 
67 /*
68  * Callback for stats handling
69  */
70 static bool
71 injection_stats_flush_cb(PgStat_EntryRef *entry_ref, bool nowait)
72 {
73  PgStat_StatInjEntry *localent;
74  PgStatShared_InjectionPoint *shfuncent;
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  return true;
84 }
85 
86 /*
87  * Support function for the SQL-callable pgstat* functions. Returns
88  * a pointer to the injection point statistics struct.
89  */
90 static PgStat_StatInjEntry *
92 {
93  PgStat_StatInjEntry *entry = NULL;
94 
96  return NULL;
97 
98  /* Compile the lookup key as a hash of the point name */
100  InvalidOid,
102  return entry;
103 }
104 
105 /*
106  * Workhorse to do the registration work, called in _PG_init().
107  */
108 void
110 {
112 
113  /* mark stats as loaded */
114  inj_stats_loaded = true;
115 }
116 
117 /*
118  * Report injection point creation.
119  */
120 void
122 {
123  PgStat_EntryRef *entry_ref;
124  PgStatShared_InjectionPoint *shstatent;
125 
126  /* leave if disabled */
128  return;
129 
131  PGSTAT_INJ_IDX(name), false);
132  shstatent = (PgStatShared_InjectionPoint *) entry_ref->shared_stats;
133 
134  /* initialize shared memory data */
135  memset(&shstatent->stats, 0, sizeof(shstatent->stats));
136  pgstat_unlock_entry(entry_ref);
137 }
138 
139 /*
140  * Report injection point drop.
141  */
142 void
143 pgstat_drop_inj(const char *name)
144 {
145  /* leave if disabled */
147  return;
148 
152 }
153 
154 /*
155  * Report statistics for injection point.
156  *
157  * This is simple because the set of stats to report currently is simple:
158  * track the number of times a point has been run.
159  */
160 void
162 {
163  PgStat_EntryRef *entry_ref;
164  PgStatShared_InjectionPoint *shstatent;
165  PgStat_StatInjEntry *statent;
166 
167  /* leave if disabled */
169  return;
170 
172  PGSTAT_INJ_IDX(name), false);
173 
174  shstatent = (PgStatShared_InjectionPoint *) entry_ref->shared_stats;
175  statent = &shstatent->stats;
176 
177  /* Update the injection point statistics */
178  statent->numcalls++;
179 
180  pgstat_unlock_entry(entry_ref);
181 }
182 
183 /*
184  * SQL function returning the number of times an injection point
185  * has been called.
186  */
188 Datum
190 {
193 
194  if (entry == NULL)
195  PG_RETURN_NULL();
196 
197  PG_RETURN_INT64(entry->numcalls);
198 }
#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 PgStat_StatInjEntry * pgstat_fetch_stat_injentry(const char *name)
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_numcalls(PG_FUNCTION_ARGS)
void * pgstat_fetch_entry(PgStat_Kind kind, Oid dboid, uint64 objid)
Definition: pgstat.c:939
void pgstat_register_kind(PgStat_Kind kind, const PgStat_KindInfo *kind_info)
Definition: pgstat.c:1472
int64 PgStat_Counter
Definition: pgstat.h:120
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:946
void pgstat_unlock_entry(PgStat_EntryRef *entry_ref)
Definition: pgstat_shmem.c:675
PgStat_EntryRef * pgstat_get_entry_ref_locked(PgStat_Kind kind, Oid dboid, uint64 objid, bool nowait)
Definition: pgstat_shmem.c:684
bool pgstat_lock_entry(PgStat_EntryRef *entry_ref, bool nowait)
Definition: pgstat_shmem.c:647
uintptr_t Datum
Definition: postgres.h:64
#define InvalidOid
Definition: postgres_ext.h:36
PgStat_StatInjEntry stats
PgStatShared_Common header
PgStatShared_Common * shared_stats
const char *const name
PgStat_Counter numcalls
char * text_to_cstring(const text *t)
Definition: varlena.c:217
const char * name