Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commita5495cd

Browse files
committed
Add a hook to let loadable modules get control at ProcessUtility execution,
and use it to extend contrib/pg_stat_statements to track utility commands.Itagaki Takahiro, reviewed by Euler Taveira de Oliveira.
1 parent34d2687 commita5495cd

File tree

4 files changed

+135
-11
lines changed

4 files changed

+135
-11
lines changed

‎contrib/pg_stat_statements/pg_stat_statements.c

Lines changed: 81 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* Copyright (c) 2008-2009, PostgreSQL Global Development Group
1515
*
1616
* IDENTIFICATION
17-
* $PostgreSQL: pgsql/contrib/pg_stat_statements/pg_stat_statements.c,v 1.8 2009/12/15 04:57:46 rhaas Exp $
17+
* $PostgreSQL: pgsql/contrib/pg_stat_statements/pg_stat_statements.c,v 1.9 2009/12/1520:04:49 tgl Exp $
1818
*
1919
*-------------------------------------------------------------------------
2020
*/
@@ -32,6 +32,7 @@
3232
#include"storage/fd.h"
3333
#include"storage/ipc.h"
3434
#include"storage/spin.h"
35+
#include"tcop/utility.h"
3536
#include"utils/builtins.h"
3637
#include"utils/hsearch.h"
3738
#include"utils/guc.h"
@@ -113,6 +114,7 @@ static shmem_startup_hook_type prev_shmem_startup_hook = NULL;
113114
staticExecutorStart_hook_typeprev_ExecutorStart=NULL;
114115
staticExecutorRun_hook_typeprev_ExecutorRun=NULL;
115116
staticExecutorEnd_hook_typeprev_ExecutorEnd=NULL;
117+
staticProcessUtility_hook_typeprev_ProcessUtility=NULL;
116118

117119
/* Links to shared memory state */
118120
staticpgssSharedState*pgss=NULL;
@@ -124,7 +126,7 @@ typedef enum
124126
{
125127
PGSS_TRACK_NONE,/* track no statements */
126128
PGSS_TRACK_TOP,/* only top level statements */
127-
PGSS_TRACK_ALL,/* all statements, including nested ones */
129+
PGSS_TRACK_ALL/* all statements, including nested ones */
128130
}PGSSTrackLevel;
129131

130132
staticconststructconfig_enum_entrytrack_options[]= {
@@ -136,6 +138,7 @@ static const struct config_enum_entry track_options[] = {
136138

137139
staticintpgss_max;/* max # statements to track */
138140
staticintpgss_track;/* tracking level */
141+
staticboolpgss_track_utility;/* whether to track utility commands */
139142
staticboolpgss_save;/* whether to save stats across shutdown */
140143

141144

@@ -161,10 +164,12 @@ static void pgss_ExecutorRun(QueryDesc *queryDesc,
161164
ScanDirectiondirection,
162165
longcount);
163166
staticvoidpgss_ExecutorEnd(QueryDesc*queryDesc);
167+
staticvoidpgss_ProcessUtility(Node*parsetree,
168+
constchar*queryString,ParamListInfoparams,boolisTopLevel,
169+
DestReceiver*dest,char*completionTag);
164170
staticuint32pgss_hash_fn(constvoid*key,Sizekeysize);
165171
staticintpgss_match_fn(constvoid*key1,constvoid*key2,Sizekeysize);
166-
staticvoidpgss_store(constchar*query,
167-
constInstrumentation*instr,uint32rows);
172+
staticvoidpgss_store(constchar*query,doubletotal_time,uint64rows);
168173
staticSizepgss_memsize(void);
169174
staticpgssEntry*entry_alloc(pgssHashKey*key);
170175
staticvoidentry_dealloc(void);
@@ -214,6 +219,16 @@ _PG_init(void)
214219
NULL,
215220
NULL);
216221

222+
DefineCustomBoolVariable("pg_stat_statements.track_utility",
223+
"Selects whether utility commands are tracked by pg_stat_statements.",
224+
NULL,
225+
&pgss_track_utility,
226+
true,
227+
PGC_SUSET,
228+
0,
229+
NULL,
230+
NULL);
231+
217232
DefineCustomBoolVariable("pg_stat_statements.save",
218233
"Save pg_stat_statements statistics across server shutdowns.",
219234
NULL,
@@ -245,6 +260,8 @@ _PG_init(void)
245260
ExecutorRun_hook=pgss_ExecutorRun;
246261
prev_ExecutorEnd=ExecutorEnd_hook;
247262
ExecutorEnd_hook=pgss_ExecutorEnd;
263+
prev_ProcessUtility=ProcessUtility_hook;
264+
ProcessUtility_hook=pgss_ProcessUtility;
248265
}
249266

250267
/*
@@ -254,10 +271,11 @@ void
254271
_PG_fini(void)
255272
{
256273
/* Uninstall hooks. */
274+
shmem_startup_hook=prev_shmem_startup_hook;
257275
ExecutorStart_hook=prev_ExecutorStart;
258276
ExecutorRun_hook=prev_ExecutorRun;
259277
ExecutorEnd_hook=prev_ExecutorEnd;
260-
shmem_startup_hook=prev_shmem_startup_hook;
278+
ProcessUtility_hook=prev_ProcessUtility;
261279
}
262280

263281
/*
@@ -539,7 +557,7 @@ pgss_ExecutorEnd(QueryDesc *queryDesc)
539557
InstrEndLoop(queryDesc->totaltime);
540558

541559
pgss_store(queryDesc->sourceText,
542-
queryDesc->totaltime,
560+
queryDesc->totaltime->total,
543561
queryDesc->estate->es_processed);
544562
}
545563

@@ -549,6 +567,61 @@ pgss_ExecutorEnd(QueryDesc *queryDesc)
549567
standard_ExecutorEnd(queryDesc);
550568
}
551569

570+
/*
571+
* ProcessUtility hook
572+
*/
573+
staticvoid
574+
pgss_ProcessUtility(Node*parsetree,constchar*queryString,
575+
ParamListInfoparams,boolisTopLevel,
576+
DestReceiver*dest,char*completionTag)
577+
{
578+
if (pgss_track_utility&&pgss_enabled())
579+
{
580+
instr_timestart;
581+
instr_timeduration;
582+
uint64rows=0;
583+
584+
INSTR_TIME_SET_CURRENT(start);
585+
586+
nested_level++;
587+
PG_TRY();
588+
{
589+
if (prev_ProcessUtility)
590+
prev_ProcessUtility(parsetree,queryString,params,
591+
isTopLevel,dest,completionTag);
592+
else
593+
standard_ProcessUtility(parsetree,queryString,params,
594+
isTopLevel,dest,completionTag);
595+
nested_level--;
596+
}
597+
PG_CATCH();
598+
{
599+
nested_level--;
600+
PG_RE_THROW();
601+
}
602+
PG_END_TRY();
603+
604+
INSTR_TIME_SET_CURRENT(duration);
605+
INSTR_TIME_SUBTRACT(duration,start);
606+
607+
/* parse command tag to retrieve the number of affected rows. */
608+
if (completionTag&&
609+
sscanf(completionTag,"COPY "UINT64_FORMAT,&rows)!=1)
610+
rows=0;
611+
612+
pgss_store(queryString,INSTR_TIME_GET_DOUBLE(duration),rows);
613+
}
614+
else
615+
{
616+
if (prev_ProcessUtility)
617+
prev_ProcessUtility(parsetree,queryString,params,
618+
isTopLevel,dest,completionTag);
619+
else
620+
standard_ProcessUtility(parsetree,queryString,params,
621+
isTopLevel,dest,completionTag);
622+
}
623+
}
624+
552625
/*
553626
* Calculate hash value for a key
554627
*/
@@ -587,7 +660,7 @@ pgss_match_fn(const void *key1, const void *key2, Size keysize)
587660
* Store some statistics for a statement.
588661
*/
589662
staticvoid
590-
pgss_store(constchar*query,constInstrumentation*instr,uint32rows)
663+
pgss_store(constchar*query,doubletotal_time,uint64rows)
591664
{
592665
pgssHashKeykey;
593666
doubleusage;
@@ -631,7 +704,7 @@ pgss_store(const char *query, const Instrumentation *instr, uint32 rows)
631704

632705
SpinLockAcquire(&e->mutex);
633706
e->counters.calls+=1;
634-
e->counters.total_time+=instr->total;
707+
e->counters.total_time+=total_time;
635708
e->counters.rows+=rows;
636709
e->counters.usage+=usage;
637710
SpinLockRelease(&e->mutex);

‎doc/src/sgml/pgstatstatements.sgml

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $PostgreSQL: pgsql/doc/src/sgml/pgstatstatements.sgml,v 1.4 2009/12/01 02:31:11 momjian Exp $ -->
1+
<!-- $PostgreSQL: pgsql/doc/src/sgml/pgstatstatements.sgml,v 1.5 2009/12/15 20:04:49 tgl Exp $ -->
22

33
<sect1 id="pgstatstatements">
44
<title>pg_stat_statements</title>
@@ -174,6 +174,23 @@
174174
</listitem>
175175
</varlistentry>
176176

177+
<varlistentry>
178+
<term>
179+
<varname>pg_stat_statements.track_utility</varname> (<type>boolean</type>)
180+
</term>
181+
182+
<listitem>
183+
<para>
184+
<varname>pg_stat_statements.track_utility</varname> controls whether
185+
utility commands are tracked by the module. Utility commands are
186+
all those other than <command>SELECT</>, <command>INSERT</>,
187+
<command>UPDATE</> and <command>DELETE</>.
188+
The default value is <literal>on</>.
189+
Only superusers can change this setting.
190+
</para>
191+
</listitem>
192+
</varlistentry>
193+
177194
<varlistentry>
178195
<term>
179196
<varname>pg_stat_statements.save</varname> (<type>boolean</type>)

‎src/backend/tcop/utility.c

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
*
1212
* IDENTIFICATION
13-
* $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.323 2009/12/11 03:34:55 itagaki Exp $
13+
* $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.324 2009/12/15 20:04:49 tgl Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -58,6 +58,10 @@
5858
#include"utils/syscache.h"
5959

6060

61+
/* Hook for plugins to get control in ProcessUtility() */
62+
ProcessUtility_hook_typeProcessUtility_hook=NULL;
63+
64+
6165
/*
6266
* Verify user has ownership of specified relation, else ereport.
6367
*
@@ -274,6 +278,27 @@ ProcessUtility(Node *parsetree,
274278
{
275279
Assert(queryString!=NULL);/* required as of 8.4 */
276280

281+
/*
282+
* We provide a function hook variable that lets loadable plugins
283+
* get control when ProcessUtility is called. Such a plugin would
284+
* normally call standard_ProcessUtility().
285+
*/
286+
if (ProcessUtility_hook)
287+
(*ProcessUtility_hook) (parsetree,queryString,params,
288+
isTopLevel,dest,completionTag);
289+
else
290+
standard_ProcessUtility(parsetree,queryString,params,
291+
isTopLevel,dest,completionTag);
292+
}
293+
294+
void
295+
standard_ProcessUtility(Node*parsetree,
296+
constchar*queryString,
297+
ParamListInfoparams,
298+
boolisTopLevel,
299+
DestReceiver*dest,
300+
char*completionTag)
301+
{
277302
check_xact_readonly(parsetree);
278303

279304
if (completionTag)

‎src/include/tcop/utility.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/tcop/utility.h,v 1.37 2009/12/01 02:31:13 momjian Exp $
10+
* $PostgreSQL: pgsql/src/include/tcop/utility.h,v 1.38 2009/12/15 20:04:49 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -17,9 +17,18 @@
1717
#include"tcop/tcopprot.h"
1818

1919

20+
/* Hook for plugins to get control in ProcessUtility() */
21+
typedefvoid (*ProcessUtility_hook_type) (Node*parsetree,
22+
constchar*queryString,ParamListInfoparams,boolisTopLevel,
23+
DestReceiver*dest,char*completionTag);
24+
externPGDLLIMPORTProcessUtility_hook_typeProcessUtility_hook;
25+
2026
externvoidProcessUtility(Node*parsetree,constchar*queryString,
2127
ParamListInfoparams,boolisTopLevel,
2228
DestReceiver*dest,char*completionTag);
29+
externvoidstandard_ProcessUtility(Node*parsetree,constchar*queryString,
30+
ParamListInfoparams,boolisTopLevel,
31+
DestReceiver*dest,char*completionTag);
2332

2433
externboolUtilityReturnsTuples(Node*parsetree);
2534

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp