diff options
Diffstat (limited to 'src/backend/utils')
-rw-r--r-- | src/backend/utils/adt/pgstatfuncs.c | 41 | ||||
-rw-r--r-- | src/backend/utils/fmgr/README | 12 | ||||
-rw-r--r-- | src/backend/utils/fmgr/fmgr.c | 39 | ||||
-rw-r--r-- | src/backend/utils/misc/guc.c | 19 | ||||
-rw-r--r-- | src/backend/utils/misc/postgresql.conf.sample | 1 |
5 files changed, 98 insertions, 14 deletions
diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c index 0750041ce5e..3e0877c7a42 100644 --- a/src/backend/utils/adt/pgstatfuncs.c +++ b/src/backend/utils/adt/pgstatfuncs.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/adt/pgstatfuncs.c,v 1.51 2008/05/12 00:00:51 alvherre Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/pgstatfuncs.c,v 1.52 2008/05/15 00:17:40 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -39,6 +39,10 @@ extern Datum pg_stat_get_last_autovacuum_time(PG_FUNCTION_ARGS); extern Datum pg_stat_get_last_analyze_time(PG_FUNCTION_ARGS); extern Datum pg_stat_get_last_autoanalyze_time(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_function_calls(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_function_time(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_function_self_time(PG_FUNCTION_ARGS); + extern Datum pg_stat_get_backend_idset(PG_FUNCTION_ARGS); extern Datum pg_stat_get_activity(PG_FUNCTION_ARGS); extern Datum pg_backend_pid(PG_FUNCTION_ARGS); @@ -326,6 +330,39 @@ pg_stat_get_last_autoanalyze_time(PG_FUNCTION_ARGS) } Datum +pg_stat_get_function_calls(PG_FUNCTION_ARGS) +{ + Oid funcid = PG_GETARG_OID(0); + PgStat_StatFuncEntry *funcentry; + + if ((funcentry = pgstat_fetch_stat_funcentry(funcid)) == NULL) + PG_RETURN_NULL(); + PG_RETURN_INT64(funcentry->f_numcalls); +} + +Datum +pg_stat_get_function_time(PG_FUNCTION_ARGS) +{ + Oid funcid = PG_GETARG_OID(0); + PgStat_StatFuncEntry *funcentry; + + if ((funcentry = pgstat_fetch_stat_funcentry(funcid)) == NULL) + PG_RETURN_NULL(); + PG_RETURN_INT64(funcentry->f_time); +} + +Datum +pg_stat_get_function_self_time(PG_FUNCTION_ARGS) +{ + Oid funcid = PG_GETARG_OID(0); + PgStat_StatFuncEntry *funcentry; + + if ((funcentry = pgstat_fetch_stat_funcentry(funcid)) == NULL) + PG_RETURN_NULL(); + PG_RETURN_INT64(funcentry->f_time_self); +} + +Datum pg_stat_get_backend_idset(PG_FUNCTION_ARGS) { FuncCallContext *funcctx; @@ -401,7 +438,7 @@ pg_stat_get_activity(PG_FUNCTION_ARGS) } else { - /* + /* * Get one backend - locate by pid. * * We lookup the backend early, so we can return zero rows if it doesn't diff --git a/src/backend/utils/fmgr/README b/src/backend/utils/fmgr/README index 730830a84ce..7cdb69418c5 100644 --- a/src/backend/utils/fmgr/README +++ b/src/backend/utils/fmgr/README @@ -1,4 +1,4 @@ -$PostgreSQL: pgsql/src/backend/utils/fmgr/README,v 1.12 2008/04/21 00:26:45 tgl Exp $ +$PostgreSQL: pgsql/src/backend/utils/fmgr/README,v 1.13 2008/05/15 00:17:40 tgl Exp $ Function Manager ================ @@ -70,6 +70,7 @@ typedef struct short fn_nargs; /* 0..FUNC_MAX_ARGS, or -1 if variable arg count */ bool fn_strict; /* function is "strict" (NULL in => NULL out) */ bool fn_retset; /* function returns a set (over multiple calls) */ + unsigned char fn_stats; /* collect stats if track_functions > this */ void *fn_extra; /* extra space for use by handler */ MemoryContext fn_mcxt; /* memory context to store fn_extra in */ Node *fn_expr; /* expression parse tree for call, or NULL */ @@ -86,10 +87,11 @@ a function handler could set it to avoid making repeated lookups of its own when the same FmgrInfo is used repeatedly during a query.) fn_nargs is the number of arguments expected by the function, fn_strict is its strictness flag, and fn_retset shows whether it returns a set; all of -these values come from the function's pg_proc entry. If the function is -being called as part of a SQL expression, fn_expr will point to the -expression parse tree for the function call; this can be used to extract -parse-time knowledge about the actual arguments. +these values come from the function's pg_proc entry. fn_stats is also +set up to control whether or not to track runtime statistics for calling +this function. If the function is being called as part of a SQL expression, +fn_expr will point to the expression parse tree for the function call; this +can be used to extract parse-time knowledge about the actual arguments. FmgrInfo already exists in the current code, but has fewer fields. This change should be transparent at the source-code level. diff --git a/src/backend/utils/fmgr/fmgr.c b/src/backend/utils/fmgr/fmgr.c index 8398305519d..481278703a9 100644 --- a/src/backend/utils/fmgr/fmgr.c +++ b/src/backend/utils/fmgr/fmgr.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/fmgr/fmgr.c,v 1.118 2008/05/12 00:00:52 alvherre Exp $ + * $PostgreSQL: pgsql/src/backend/utils/fmgr/fmgr.c,v 1.119 2008/05/15 00:17:40 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -21,6 +21,7 @@ #include "executor/functions.h" #include "miscadmin.h" #include "parser/parse_expr.h" +#include "pgstat.h" #include "utils/builtins.h" #include "utils/fmgrtab.h" #include "utils/guc.h" @@ -165,8 +166,7 @@ fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt) /* * This one does the actual work. ignore_security is ordinarily false - * but is set to true by fmgr_security_definer to avoid infinite - * recursive lookups. + * but is set to true by fmgr_security_definer to avoid recursion. */ static void fmgr_info_cxt_security(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt, @@ -197,6 +197,7 @@ fmgr_info_cxt_security(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt, finfo->fn_nargs = fbp->nargs; finfo->fn_strict = fbp->strict; finfo->fn_retset = fbp->retset; + finfo->fn_stats = TRACK_FUNC_ALL; /* ie, never track */ finfo->fn_addr = fbp->func; finfo->fn_oid = functionId; return; @@ -216,13 +217,23 @@ fmgr_info_cxt_security(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt, /* * If it has prosecdef set, or non-null proconfig, use - * fmgr_security_definer call handler. + * fmgr_security_definer call handler --- unless we are being called + * again by fmgr_security_definer. + * + * When using fmgr_security_definer, function stats tracking is always + * disabled at the outer level, and instead we set the flag properly + * in fmgr_security_definer's private flinfo and implement the tracking + * inside fmgr_security_definer. This loses the ability to charge the + * overhead of fmgr_security_definer to the function, but gains the + * ability to set the track_functions GUC as a local GUC parameter of + * an interesting function and have the right things happen. */ if (!ignore_security && (procedureStruct->prosecdef || !heap_attisnull(procedureTuple, Anum_pg_proc_proconfig))) { finfo->fn_addr = fmgr_security_definer; + finfo->fn_stats = TRACK_FUNC_ALL; /* ie, never track */ finfo->fn_oid = functionId; ReleaseSysCache(procedureTuple); return; @@ -255,18 +266,23 @@ fmgr_info_cxt_security(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt, pfree(prosrc); /* Should we check that nargs, strict, retset match the table? */ finfo->fn_addr = fbp->func; + /* note this policy is also assumed in fast path above */ + finfo->fn_stats = TRACK_FUNC_ALL; /* ie, never track */ break; case ClanguageId: fmgr_info_C_lang(functionId, finfo, procedureTuple); + finfo->fn_stats = TRACK_FUNC_PL; /* ie, track if ALL */ break; case SQLlanguageId: finfo->fn_addr = fmgr_sql; + finfo->fn_stats = TRACK_FUNC_PL; /* ie, track if ALL */ break; default: fmgr_info_other_lang(functionId, finfo, procedureTuple); + finfo->fn_stats = TRACK_FUNC_OFF; /* ie, track if not OFF */ break; } @@ -862,6 +878,7 @@ fmgr_security_definer(PG_FUNCTION_ARGS) Oid save_userid; bool save_secdefcxt; volatile int save_nestlevel; + PgStat_FunctionCallUsage fcusage; if (!fcinfo->flinfo->fn_extra) { @@ -934,7 +951,19 @@ fmgr_security_definer(PG_FUNCTION_ARGS) { fcinfo->flinfo = &fcache->flinfo; + /* See notes in fmgr_info_cxt_security */ + pgstat_init_function_usage(fcinfo, &fcusage); + result = FunctionCallInvoke(fcinfo); + + /* + * We could be calling either a regular or a set-returning function, + * so we have to test to see what finalize flag to use. + */ + pgstat_end_function_usage(&fcusage, + (fcinfo->resultinfo == NULL || + !IsA(fcinfo->resultinfo, ReturnSetInfo) || + ((ReturnSetInfo *) fcinfo->resultinfo)->isDone != ExprMultipleResult)); } PG_CATCH(); { @@ -2089,7 +2118,7 @@ float4 DatumGetFloat4(Datum X) { union { - int32 value; + int32 value; float4 retval; } myunion; diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index c4b07aad2a4..f4466ddb141 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -10,7 +10,7 @@ * Written by Peter Eisentraut <peter_e@gmx.net>. * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.453 2008/05/12 08:35:05 mha Exp $ + * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.454 2008/05/15 00:17:40 tgl Exp $ * *-------------------------------------------------------------------- */ @@ -169,7 +169,6 @@ static char *config_enum_get_options(struct config_enum *record, const char *prefix, const char *suffix); - /* * Options for enum values defined in this module. */ @@ -241,6 +240,13 @@ static const struct config_enum_entry syslog_facility_options[] = { }; #endif +static const struct config_enum_entry track_function_options[] = { + {"none", TRACK_FUNC_OFF}, + {"pl", TRACK_FUNC_PL}, + {"all", TRACK_FUNC_ALL}, + {NULL, 0} +}; + static const struct config_enum_entry xmlbinary_options[] = { {"base64", XMLBINARY_BASE64}, {"hex", XMLBINARY_HEX}, @@ -2525,6 +2531,15 @@ static struct config_enum ConfigureNamesEnum[] = }, { + {"track_functions", PGC_SUSET, STATS_COLLECTOR, + gettext_noop("Collects function-level statistics on database activity."), + gettext_noop("Valid values are: NONE, PL, and ALL.") + }, + &pgstat_track_functions, + TRACK_FUNC_OFF, track_function_options, NULL, NULL + }, + + { {"wal_sync_method", PGC_SIGHUP, WAL_SETTINGS, gettext_noop("Selects the method used for forcing WAL updates to disk."), NULL diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample index ce784530832..fdc6f39fc29 100644 --- a/src/backend/utils/misc/postgresql.conf.sample +++ b/src/backend/utils/misc/postgresql.conf.sample @@ -363,6 +363,7 @@ #track_activities = on #track_counts = on +#track_functions = none # none, pl, all #update_process_title = on |