PostgreSQL Source Code  git master
pgstat_function.c File Reference
#include "postgres.h"
#include "fmgr.h"
#include "utils/inval.h"
#include "utils/pgstat_internal.h"
#include "utils/syscache.h"
Include dependency graph for pgstat_function.c:

Go to the source code of this file.

Functions

void pgstat_create_function (Oid proid)
 
void pgstat_drop_function (Oid proid)
 
void pgstat_init_function_usage (FunctionCallInfo fcinfo, PgStat_FunctionCallUsage *fcu)
 
void pgstat_end_function_usage (PgStat_FunctionCallUsage *fcu, bool finalize)
 
bool pgstat_function_flush_cb (PgStat_EntryRef *entry_ref, bool nowait)
 
PgStat_FunctionCountsfind_funcstat_entry (Oid func_id)
 
PgStat_StatFuncEntrypgstat_fetch_stat_funcentry (Oid func_id)
 

Variables

int pgstat_track_functions = TRACK_FUNC_OFF
 
static instr_time total_func_time
 

Function Documentation

◆ find_funcstat_entry()

PgStat_FunctionCounts* find_funcstat_entry ( Oid  func_id)

Definition at line 223 of file pgstat_function.c.

224 {
225  PgStat_EntryRef *entry_ref;
226 
228 
229  if (entry_ref)
230  return entry_ref->pending;
231  return NULL;
232 }
Oid MyDatabaseId
Definition: globals.c:91
PgStat_EntryRef * pgstat_fetch_pending_entry(PgStat_Kind kind, Oid dboid, Oid objoid)
Definition: pgstat.c:1143
@ PGSTAT_KIND_FUNCTION
Definition: pgstat.h:43

References MyDatabaseId, PgStat_EntryRef::pending, pgstat_fetch_pending_entry(), and PGSTAT_KIND_FUNCTION.

Referenced by pg_stat_get_xact_function_calls().

◆ pgstat_create_function()

void pgstat_create_function ( Oid  proid)

Definition at line 45 of file pgstat_function.c.

46 {
49  proid);
50 }
void pgstat_create_transactional(PgStat_Kind kind, Oid dboid, Oid objoid)
Definition: pgstat_xact.c:357

References MyDatabaseId, pgstat_create_transactional(), and PGSTAT_KIND_FUNCTION.

Referenced by ProcedureCreate().

◆ pgstat_drop_function()

void pgstat_drop_function ( Oid  proid)

Definition at line 60 of file pgstat_function.c.

61 {
64  proid);
65 }
void pgstat_drop_transactional(PgStat_Kind kind, Oid dboid, Oid objoid)
Definition: pgstat_xact.c:379

References MyDatabaseId, pgstat_drop_transactional(), and PGSTAT_KIND_FUNCTION.

Referenced by RemoveFunctionById().

◆ pgstat_end_function_usage()

void pgstat_end_function_usage ( PgStat_FunctionCallUsage fcu,
bool  finalize 
)

Definition at line 146 of file pgstat_function.c.

147 {
148  PgStat_FunctionCounts *fs = fcu->fs;
149  instr_time total;
150  instr_time others;
151  instr_time self;
152 
153  /* stats not wanted? */
154  if (fs == NULL)
155  return;
156 
157  /* total elapsed time in this function call */
158  INSTR_TIME_SET_CURRENT(total);
159  INSTR_TIME_SUBTRACT(total, fcu->start);
160 
161  /* self usage: elapsed minus anything already charged to other calls */
162  others = total_func_time;
163  INSTR_TIME_SUBTRACT(others, fcu->save_total);
164  self = total;
165  INSTR_TIME_SUBTRACT(self, others);
166 
167  /* update backend-wide total time */
169 
170  /*
171  * Compute the new total_time as the total elapsed time added to the
172  * pre-call value of total_time. This is necessary to avoid
173  * double-counting any time taken by recursive calls of myself. (We do
174  * not need any similar kluge for self time, since that already excludes
175  * any recursive calls.)
176  */
177  INSTR_TIME_ADD(total, fcu->save_f_total_time);
178 
179  /* update counters in function stats table */
180  if (finalize)
181  fs->numcalls++;
182  fs->total_time = total;
183  INSTR_TIME_ADD(fs->self_time, self);
184 }
#define INSTR_TIME_SET_CURRENT(t)
Definition: instr_time.h:122
#define INSTR_TIME_ADD(x, y)
Definition: instr_time.h:178
#define INSTR_TIME_SUBTRACT(x, y)
Definition: instr_time.h:181
static instr_time total_func_time
instr_time save_total
Definition: pgstat.h:125
PgStat_FunctionCounts * fs
Definition: pgstat.h:121
instr_time save_f_total_time
Definition: pgstat.h:123
PgStat_Counter numcalls
Definition: pgstat.h:109
instr_time total_time
Definition: pgstat.h:110
instr_time self_time
Definition: pgstat.h:111

References PgStat_FunctionCallUsage::fs, INSTR_TIME_ADD, INSTR_TIME_SET_CURRENT, INSTR_TIME_SUBTRACT, PgStat_FunctionCounts::numcalls, PgStat_FunctionCallUsage::save_f_total_time, PgStat_FunctionCallUsage::save_total, PgStat_FunctionCounts::self_time, PgStat_FunctionCallUsage::start, total_func_time, and PgStat_FunctionCounts::total_time.

Referenced by call_pltcl_start_proc(), EventTriggerInvoke(), ExecCallTriggerFunc(), ExecEvalFuncExprFusage(), ExecEvalFuncExprStrictFusage(), ExecMakeFunctionResultSet(), ExecMakeTableFunctionResult(), ExecuteCallStmt(), and fmgr_security_definer().

◆ pgstat_fetch_stat_funcentry()

PgStat_StatFuncEntry* pgstat_fetch_stat_funcentry ( Oid  func_id)

Definition at line 239 of file pgstat_function.c.

240 {
241  return (PgStat_StatFuncEntry *)
243 }
void * pgstat_fetch_entry(PgStat_Kind kind, Oid dboid, Oid objoid)
Definition: pgstat.c:812

References MyDatabaseId, pgstat_fetch_entry(), and PGSTAT_KIND_FUNCTION.

Referenced by pg_stat_get_function_calls().

◆ pgstat_function_flush_cb()

bool pgstat_function_flush_cb ( PgStat_EntryRef entry_ref,
bool  nowait 
)

Definition at line 193 of file pgstat_function.c.

194 {
195  PgStat_FunctionCounts *localent;
196  PgStatShared_Function *shfuncent;
197 
198  localent = (PgStat_FunctionCounts *) entry_ref->pending;
199  shfuncent = (PgStatShared_Function *) entry_ref->shared_stats;
200 
201  /* localent always has non-zero content */
202 
203  if (!pgstat_lock_entry(entry_ref, nowait))
204  return false;
205 
206  shfuncent->stats.numcalls += localent->numcalls;
207  shfuncent->stats.total_time +=
209  shfuncent->stats.self_time +=
211 
212  pgstat_unlock_entry(entry_ref);
213 
214  return true;
215 }
#define INSTR_TIME_GET_MICROSEC(t)
Definition: instr_time.h:194
void pgstat_unlock_entry(PgStat_EntryRef *entry_ref)
Definition: pgstat_shmem.c:604
bool pgstat_lock_entry(PgStat_EntryRef *entry_ref, bool nowait)
Definition: pgstat_shmem.c:576
PgStat_StatFuncEntry stats
PgStatShared_Common * shared_stats
PgStat_Counter self_time
Definition: pgstat.h:364
PgStat_Counter numcalls
Definition: pgstat.h:361
PgStat_Counter total_time
Definition: pgstat.h:363

References INSTR_TIME_GET_MICROSEC, PgStat_FunctionCounts::numcalls, PgStat_StatFuncEntry::numcalls, PgStat_EntryRef::pending, pgstat_lock_entry(), pgstat_unlock_entry(), PgStat_FunctionCounts::self_time, PgStat_StatFuncEntry::self_time, PgStat_EntryRef::shared_stats, PgStatShared_Function::stats, PgStat_FunctionCounts::total_time, and PgStat_StatFuncEntry::total_time.

◆ pgstat_init_function_usage()

void pgstat_init_function_usage ( FunctionCallInfo  fcinfo,
PgStat_FunctionCallUsage fcu 
)

Definition at line 72 of file pgstat_function.c.

74 {
75  PgStat_EntryRef *entry_ref;
76  PgStat_FunctionCounts *pending;
77  bool created_entry;
78 
79  if (pgstat_track_functions <= fcinfo->flinfo->fn_stats)
80  {
81  /* stats not wanted */
82  fcu->fs = NULL;
83  return;
84  }
85 
88  fcinfo->flinfo->fn_oid,
89  &created_entry);
90 
91  /*
92  * If no shared entry already exists, check if the function has been
93  * deleted concurrently. This can go unnoticed until here because
94  * executing a statement that just calls a function, does not trigger
95  * cache invalidation processing. The reason we care about this case is
96  * that otherwise we could create a new stats entry for an already dropped
97  * function (for relations etc this is not possible because emitting stats
98  * requires a lock for the relation to already have been acquired).
99  *
100  * It's somewhat ugly to have a behavioral difference based on
101  * track_functions being enabled/disabled. But it seems acceptable, given
102  * that there's already behavioral differences depending on whether the
103  * function is the caches etc.
104  *
105  * For correctness it'd be sufficient to set ->dropped to true. However,
106  * the accepted invalidation will commonly cause "low level" failures in
107  * PL code, with an OID in the error message. Making this harder to
108  * test...
109  */
110  if (created_entry)
111  {
113  if (!SearchSysCacheExists1(PROCOID, ObjectIdGetDatum(fcinfo->flinfo->fn_oid)))
114  {
116  fcinfo->flinfo->fn_oid);
117  ereport(ERROR, errcode(ERRCODE_UNDEFINED_FUNCTION),
118  errmsg("function call to dropped function"));
119  }
120  }
121 
122  pending = entry_ref->pending;
123 
124  fcu->fs = pending;
125 
126  /* save stats for this function, later used to compensate for recursion */
127  fcu->save_f_total_time = pending->total_time;
128 
129  /* save current backend-wide total time */
131 
132  /* get clock time as of function start */
134 }
int errcode(int sqlerrcode)
Definition: elog.c:859
int errmsg(const char *fmt,...)
Definition: elog.c:1072
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
void AcceptInvalidationMessages(void)
Definition: inval.c:806
PgStat_EntryRef * pgstat_prep_pending_entry(PgStat_Kind kind, Oid dboid, Oid objoid, bool *created_entry)
Definition: pgstat.c:1105
bool pgstat_drop_entry(PgStat_Kind kind, Oid dboid, Oid objoid)
Definition: pgstat_shmem.c:859
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:252
Oid fn_oid
Definition: fmgr.h:59
FmgrInfo * flinfo
Definition: fmgr.h:87
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:95

References AcceptInvalidationMessages(), ereport, errcode(), errmsg(), ERROR, FunctionCallInfoBaseData::flinfo, FmgrInfo::fn_oid, PgStat_FunctionCallUsage::fs, INSTR_TIME_SET_CURRENT, MyDatabaseId, ObjectIdGetDatum(), PgStat_EntryRef::pending, pgstat_drop_entry(), PGSTAT_KIND_FUNCTION, pgstat_prep_pending_entry(), PgStat_FunctionCallUsage::save_f_total_time, PgStat_FunctionCallUsage::save_total, SearchSysCacheExists1, PgStat_FunctionCallUsage::start, total_func_time, and PgStat_FunctionCounts::total_time.

Referenced by call_pltcl_start_proc(), EventTriggerInvoke(), ExecCallTriggerFunc(), ExecEvalFuncExprFusage(), ExecEvalFuncExprStrictFusage(), ExecMakeFunctionResultSet(), ExecMakeTableFunctionResult(), ExecuteCallStmt(), and fmgr_security_definer().

Variable Documentation

◆ pgstat_track_functions

int pgstat_track_functions = TRACK_FUNC_OFF

Definition at line 30 of file pgstat_function.c.

◆ total_func_time

instr_time total_func_time
static

Definition at line 38 of file pgstat_function.c.

Referenced by pgstat_end_function_usage(), and pgstat_init_function_usage().