Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 93c701e

Browse files
committed
Add support for tracking call counts and elapsed runtime for user-defined
functions. Note that because this patch changes FmgrInfo, any external C functions you might be testing with 8.4 will need to be recompiled. Patch by Martin Pihlak, some editorialization by me (principally, removing tracking of getrusage() numbers)
1 parent 3bc2538 commit 93c701e

File tree

20 files changed

+830
-67
lines changed

20 files changed

+830
-67
lines changed

doc/src/sgml/config.sgml

+17-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.177 2008/05/02 21:26:09 tgl Exp $ -->
1+
<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.178 2008/05/15 00:17:39 tgl Exp $ -->
22

33
<chapter Id="runtime-config">
44
<title>Server Configuration</title>
@@ -3342,6 +3342,22 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
33423342
</listitem>
33433343
</varlistentry>
33443344

3345+
<varlistentry id="guc-track-functions" xreflabel="track_functions">
3346+
<term><varname>track_functions</varname> (<type>string</type>)</term>
3347+
<indexterm>
3348+
<primary><varname>track_functions</> configuration parameter</primary>
3349+
</indexterm>
3350+
<listitem>
3351+
<para>
3352+
Enables tracking of function call counts and time used. Specify
3353+
<literal>pl</literal> to count only procedural language functions,
3354+
<literal>all</literal> to also track SQL and C language functions.
3355+
The default is <literal>none</literal>.
3356+
Only superusers can change this setting.
3357+
</para>
3358+
</listitem>
3359+
</varlistentry>
3360+
33453361
<varlistentry id="guc-update-process-title" xreflabel="update_process_title">
33463362
<term><varname>update_process_title</varname> (<type>boolean</type>)</term>
33473363
<indexterm>

doc/src/sgml/monitoring.sgml

+49-7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $PostgreSQL: pgsql/doc/src/sgml/monitoring.sgml,v 1.58 2008/05/07 14:41:55 mha Exp $ -->
1+
<!-- $PostgreSQL: pgsql/doc/src/sgml/monitoring.sgml,v 1.59 2008/05/15 00:17:39 tgl Exp $ -->
22

33
<chapter id="monitoring">
44
<title>Monitoring Database Activity</title>
@@ -119,7 +119,8 @@ postgres: <replaceable>user</> <replaceable>database</> <replaceable>host</> <re
119119
server activity. Presently, the collector can count accesses to tables
120120
and indexes in both disk-block and individual-row terms. It also tracks
121121
total numbers of rows in each table, and the last vacuum and analyze times
122-
for each table.
122+
for each table. It can also count calls to user-defined functions and
123+
the total time spent in each one.
123124
</para>
124125

125126
<para>
@@ -141,15 +142,19 @@ postgres: <replaceable>user</> <replaceable>database</> <replaceable>host</> <re
141142

142143
<para>
143144
The parameter <xref linkend="guc-track-counts"> controls whether
144-
information is actually sent to the collector process and thus determines
145-
whether any run-time overhead occurs for event counting.
145+
statistics are collected about table and index accesses.
146+
</para>
147+
148+
<para>
149+
The parameter <xref linkend="guc-track-functions"> enables tracking of
150+
usage of user-defined functions.
146151
</para>
147152

148153
<para>
149154
The parameter <xref linkend="guc-track-activities"> enables monitoring
150155
of the current command being executed by any server process.
151156
</para>
152-
157+
153158
<para>
154159
Normally these parameters are set in <filename>postgresql.conf</> so
155160
that they apply to all server processes, but it is possible to turn
@@ -370,6 +375,16 @@ postgres: <replaceable>user</> <replaceable>database</> <replaceable>host</> <re
370375
<entry>Same as <structname>pg_statio_all_sequences</>, except that only
371376
user sequences are shown.</entry>
372377
</row>
378+
379+
<row>
380+
<entry><structname>pg_stat_user_functions</></entry>
381+
<entry>For all tracked functions, function OID, schema, name, number
382+
of calls, total time, and self time. Self time is the
383+
amount of time spent in the function itself, total time includes the
384+
time spent in functions it called. Time values are in milliseconds.
385+
</entry>
386+
</row>
387+
373388
</tbody>
374389
</tgroup>
375390
</table>
@@ -429,8 +444,9 @@ postgres: <replaceable>user</> <replaceable>database</> <replaceable>host</> <re
429444
linkend="monitoring-stats-funcs-table">. The per-database access
430445
functions take a database OID as argument to identify which
431446
database to report on. The per-table and per-index functions take
432-
a table or index OID. (Note that only tables and indexes in the
433-
current database can be seen with these functions.) The
447+
a table or index OID. The functions for function-call statistics
448+
take a function OID. (Note that only tables, indexes, and functions
449+
in the current database can be seen with these functions.) The
434450
per-server-process access functions take a server process
435451
number, which ranges from one to the number of currently active
436452
server processes.
@@ -674,6 +690,32 @@ postgres: <replaceable>user</> <replaceable>database</> <replaceable>host</> <re
674690
</entry>
675691
</row>
676692

693+
<row>
694+
<entry><literal><function>pg_stat_get_function_calls</function>(<type>oid</type>)</literal></entry>
695+
<entry><type>bigint</type></entry>
696+
<entry>
697+
Number of times the function has been called.
698+
</entry>
699+
</row>
700+
701+
<row>
702+
<entry><literal><function>pg_stat_get_function_time</function>(<type>oid</type>)</literal></entry>
703+
<entry><type>bigint</type></entry>
704+
<entry>
705+
Total wall clock time spent in the function, in microseconds. Includes
706+
the time spent in functions called by this one.
707+
</entry>
708+
</row>
709+
710+
<row>
711+
<entry><literal><function>pg_stat_get_function_self_time</function>(<type>oid</type>)</literal></entry>
712+
<entry><type>bigint</type></entry>
713+
<entry>
714+
Time spent in only this function. Time spent in called functions
715+
is excluded.
716+
</entry>
717+
</row>
718+
677719
<row>
678720
<entry><literal><function>pg_stat_get_backend_idset</function>()</literal></entry>
679721
<entry><type>setof integer</type></entry>

src/backend/catalog/system_views.sql

+13-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*
44
* Copyright (c) 1996-2008, PostgreSQL Global Development Group
55
*
6-
* $PostgreSQL: pgsql/src/backend/catalog/system_views.sql,v 1.51 2008/05/08 08:58:59 mha Exp $
6+
* $PostgreSQL: pgsql/src/backend/catalog/system_views.sql,v 1.52 2008/05/15 00:17:39 tgl Exp $
77
*/
88

99
CREATE VIEW pg_roles AS
@@ -374,6 +374,18 @@ CREATE VIEW pg_stat_database AS
374374
pg_stat_get_db_tuples_deleted(D.oid) AS tup_deleted
375375
FROM pg_database D;
376376

377+
CREATE VIEW pg_stat_user_functions AS
378+
SELECT
379+
P.oid AS funcid,
380+
N.nspname AS schemaname,
381+
P.proname AS funcname,
382+
pg_stat_get_function_calls(P.oid) AS calls,
383+
pg_stat_get_function_time(P.oid) / 1000 AS total_time,
384+
pg_stat_get_function_self_time(P.oid) / 1000 AS self_time
385+
FROM pg_proc P LEFT JOIN pg_namespace N ON (N.oid = P.pronamespace)
386+
WHERE P.prolang != 12 -- fast check to eliminate built-in functions
387+
AND pg_stat_get_function_calls(P.oid) IS NOT NULL;
388+
377389
CREATE VIEW pg_stat_bgwriter AS
378390
SELECT
379391
pg_stat_get_bgwriter_timed_checkpoints() AS checkpoints_timed,

src/backend/commands/trigger.c

+7-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
99
* IDENTIFICATION
10-
* $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.233 2008/05/12 20:01:59 alvherre Exp $
10+
* $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.234 2008/05/15 00:17:39 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -32,6 +32,7 @@
3232
#include "miscadmin.h"
3333
#include "nodes/makefuncs.h"
3434
#include "parser/parse_func.h"
35+
#include "pgstat.h"
3536
#include "storage/bufmgr.h"
3637
#include "tcop/utility.h"
3738
#include "utils/acl.h"
@@ -1566,6 +1567,7 @@ ExecCallTriggerFunc(TriggerData *trigdata,
15661567
MemoryContext per_tuple_context)
15671568
{
15681569
FunctionCallInfoData fcinfo;
1570+
PgStat_FunctionCallUsage fcusage;
15691571
Datum result;
15701572
MemoryContext oldContext;
15711573

@@ -1599,8 +1601,12 @@ ExecCallTriggerFunc(TriggerData *trigdata,
15991601
*/
16001602
InitFunctionCallInfoData(fcinfo, finfo, 0, (Node *) trigdata, NULL);
16011603

1604+
pgstat_init_function_usage(&fcinfo, &fcusage);
1605+
16021606
result = FunctionCallInvoke(&fcinfo);
16031607

1608+
pgstat_end_function_usage(&fcusage, true);
1609+
16041610
MemoryContextSwitchTo(oldContext);
16051611

16061612
/*

src/backend/commands/vacuum.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
*
1414
*
1515
* IDENTIFICATION
16-
* $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.373 2008/05/12 20:02:00 alvherre Exp $
16+
* $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.374 2008/05/15 00:17:39 tgl Exp $
1717
*
1818
*-------------------------------------------------------------------------
1919
*/
@@ -323,7 +323,7 @@ vacuum(VacuumStmt *vacstmt, List *relids,
323323
* in autovacuum --- autovacuum.c does this for itself.
324324
*/
325325
if (vacstmt->vacuum && !IsAutoVacuumWorkerProcess())
326-
pgstat_vacuum_tabstat();
326+
pgstat_vacuum_stat();
327327

328328
/*
329329
* Create special memory context for cross-transaction storage.

src/backend/executor/execQual.c

+25-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.230 2008/05/12 00:00:48 alvherre Exp $
11+
* $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.231 2008/05/15 00:17:39 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -46,6 +46,7 @@
4646
#include "nodes/makefuncs.h"
4747
#include "optimizer/planmain.h"
4848
#include "parser/parse_expr.h"
49+
#include "pgstat.h"
4950
#include "utils/acl.h"
5051
#include "utils/builtins.h"
5152
#include "utils/lsyscache.h"
@@ -1147,6 +1148,7 @@ ExecMakeFunctionResult(FuncExprState *fcache,
11471148
List *arguments = fcache->args;
11481149
Datum result;
11491150
FunctionCallInfoData fcinfo;
1151+
PgStat_FunctionCallUsage fcusage;
11501152
ReturnSetInfo rsinfo; /* for functions returning sets */
11511153
ExprDoneCond argDone;
11521154
bool hasSetArg;
@@ -1250,11 +1252,16 @@ ExecMakeFunctionResult(FuncExprState *fcache,
12501252

12511253
if (callit)
12521254
{
1255+
pgstat_init_function_usage(&fcinfo, &fcusage);
1256+
12531257
fcinfo.isnull = false;
12541258
rsinfo.isDone = ExprSingleResult;
12551259
result = FunctionCallInvoke(&fcinfo);
12561260
*isNull = fcinfo.isnull;
12571261
*isDone = rsinfo.isDone;
1262+
1263+
pgstat_end_function_usage(&fcusage,
1264+
rsinfo.isDone != ExprMultipleResult);
12581265
}
12591266
else
12601267
{
@@ -1346,9 +1353,14 @@ ExecMakeFunctionResult(FuncExprState *fcache,
13461353
}
13471354
}
13481355
}
1356+
1357+
pgstat_init_function_usage(&fcinfo, &fcusage);
1358+
13491359
fcinfo.isnull = false;
13501360
result = FunctionCallInvoke(&fcinfo);
13511361
*isNull = fcinfo.isnull;
1362+
1363+
pgstat_end_function_usage(&fcusage, true);
13521364
}
13531365

13541366
return result;
@@ -1369,6 +1381,7 @@ ExecMakeFunctionResultNoSets(FuncExprState *fcache,
13691381
ListCell *arg;
13701382
Datum result;
13711383
FunctionCallInfoData fcinfo;
1384+
PgStat_FunctionCallUsage fcusage;
13721385
int i;
13731386

13741387
/* Guard against stack overflow due to overly complex expressions */
@@ -1407,10 +1420,15 @@ ExecMakeFunctionResultNoSets(FuncExprState *fcache,
14071420
}
14081421
}
14091422
}
1423+
1424+
pgstat_init_function_usage(&fcinfo, &fcusage);
1425+
14101426
/* fcinfo.isnull = false; */ /* handled by InitFunctionCallInfoData */
14111427
result = FunctionCallInvoke(&fcinfo);
14121428
*isNull = fcinfo.isnull;
14131429

1430+
pgstat_end_function_usage(&fcusage, true);
1431+
14141432
return result;
14151433
}
14161434

@@ -1434,6 +1452,7 @@ ExecMakeTableFunctionResult(ExprState *funcexpr,
14341452
bool returnsTuple;
14351453
bool returnsSet = false;
14361454
FunctionCallInfoData fcinfo;
1455+
PgStat_FunctionCallUsage fcusage;
14371456
ReturnSetInfo rsinfo;
14381457
HeapTupleData tmptup;
14391458
MemoryContext callerContext;
@@ -1559,9 +1578,14 @@ ExecMakeTableFunctionResult(ExprState *funcexpr,
15591578
/* Call the function or expression one time */
15601579
if (direct_function_call)
15611580
{
1581+
pgstat_init_function_usage(&fcinfo, &fcusage);
1582+
15621583
fcinfo.isnull = false;
15631584
rsinfo.isDone = ExprSingleResult;
15641585
result = FunctionCallInvoke(&fcinfo);
1586+
1587+
pgstat_end_function_usage(&fcusage,
1588+
rsinfo.isDone != ExprMultipleResult);
15651589
}
15661590
else
15671591
{

src/backend/postmaster/autovacuum.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
*
5656
*
5757
* IDENTIFICATION
58-
* $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.77 2008/05/12 00:00:50 alvherre Exp $
58+
* $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.78 2008/05/15 00:17:40 tgl Exp $
5959
*
6060
*-------------------------------------------------------------------------
6161
*/
@@ -1857,7 +1857,7 @@ do_autovacuum(void)
18571857
* want to do this exactly once per DB-processing cycle, even if we find
18581858
* nothing worth vacuuming in the database.
18591859
*/
1860-
pgstat_vacuum_tabstat();
1860+
pgstat_vacuum_stat();
18611861

18621862
/*
18631863
* Find the pg_database entry and select the default freeze_min_age. We

0 commit comments

Comments
 (0)