14
14
* Copyright (c) 2008-2010, PostgreSQL Global Development Group
15
15
*
16
16
* IDENTIFICATION
17
- * $PostgreSQL: pgsql/contrib/pg_stat_statements/pg_stat_statements.c,v 1.11 2010/01/02 16:57:32 momjian Exp $
17
+ * $PostgreSQL: pgsql/contrib/pg_stat_statements/pg_stat_statements.c,v 1.12 2010/01/08 00:38:19 itagaki Exp $
18
18
*
19
19
*-------------------------------------------------------------------------
20
20
*/
26
26
#include "catalog/pg_type.h"
27
27
#include "executor/executor.h"
28
28
#include "executor/instrument.h"
29
+ #include "funcapi.h"
29
30
#include "mb/pg_wchar.h"
30
31
#include "miscadmin.h"
31
32
#include "pgstat.h"
@@ -44,7 +45,7 @@ PG_MODULE_MAGIC;
44
45
#define PGSS_DUMP_FILE "global/pg_stat_statements.stat"
45
46
46
47
/* This constant defines the magic number in the stats file header */
47
- static const uint32 PGSS_FILE_HEADER = 0x20081202 ;
48
+ static const uint32 PGSS_FILE_HEADER = 0x20100108 ;
48
49
49
50
/* XXX: Should USAGE_EXEC reflect execution time and/or buffer usage? */
50
51
#define USAGE_EXEC (duration ) (1.0)
@@ -75,10 +76,18 @@ typedef struct pgssHashKey
75
76
*/
76
77
typedef struct Counters
77
78
{
78
- int64 calls ; /* # of times executed */
79
- double total_time ; /* total execution time in seconds */
80
- int64 rows ; /* total # of retrieved or affected rows */
81
- double usage ; /* usage factor */
79
+ int64 calls ; /* # of times executed */
80
+ double total_time ; /* total execution time in seconds */
81
+ int64 rows ; /* total # of retrieved or affected rows */
82
+ int64 shared_blks_hit ; /* # of shared buffer hits */
83
+ int64 shared_blks_read ; /* # of shared disk blocks read */
84
+ int64 shared_blks_written ;/* # of shared disk blocks written */
85
+ int64 local_blks_hit ; /* # of local buffer hits */
86
+ int64 local_blks_read ; /* # of local disk blocks read */
87
+ int64 local_blks_written ; /* # of local disk blocks written */
88
+ int64 temp_blks_read ; /* # of temp blocks read */
89
+ int64 temp_blks_written ; /* # of temp blocks written */
90
+ double usage ; /* usage factor */
82
91
} Counters ;
83
92
84
93
/*
@@ -129,7 +138,8 @@ typedef enum
129
138
PGSS_TRACK_ALL /* all statements, including nested ones */
130
139
} PGSSTrackLevel ;
131
140
132
- static const struct config_enum_entry track_options [] = {
141
+ static const struct config_enum_entry track_options [] =
142
+ {
133
143
{"none" , PGSS_TRACK_NONE , false},
134
144
{"top" , PGSS_TRACK_TOP , false},
135
145
{"all" , PGSS_TRACK_ALL , false},
@@ -169,7 +179,8 @@ static void pgss_ProcessUtility(Node *parsetree,
169
179
DestReceiver * dest , char * completionTag );
170
180
static uint32 pgss_hash_fn (const void * key , Size keysize );
171
181
static int pgss_match_fn (const void * key1 , const void * key2 , Size keysize );
172
- static void pgss_store (const char * query , double total_time , uint64 rows );
182
+ static void pgss_store (const char * query , double total_time , uint64 rows ,
183
+ const BufferUsage * bufusage );
173
184
static Size pgss_memsize (void );
174
185
static pgssEntry * entry_alloc (pgssHashKey * key );
175
186
static void entry_dealloc (void );
@@ -558,7 +569,8 @@ pgss_ExecutorEnd(QueryDesc *queryDesc)
558
569
559
570
pgss_store (queryDesc -> sourceText ,
560
571
queryDesc -> totaltime -> total ,
561
- queryDesc -> estate -> es_processed );
572
+ queryDesc -> estate -> es_processed ,
573
+ & queryDesc -> totaltime -> bufusage );
562
574
}
563
575
564
576
if (prev_ExecutorEnd )
@@ -580,7 +592,9 @@ pgss_ProcessUtility(Node *parsetree, const char *queryString,
580
592
instr_time start ;
581
593
instr_time duration ;
582
594
uint64 rows = 0 ;
595
+ BufferUsage bufusage ;
583
596
597
+ bufusage = pgBufferUsage ;
584
598
INSTR_TIME_SET_CURRENT (start );
585
599
586
600
nested_level ++ ;
@@ -609,7 +623,26 @@ pgss_ProcessUtility(Node *parsetree, const char *queryString,
609
623
sscanf (completionTag , "COPY " UINT64_FORMAT , & rows ) != 1 )
610
624
rows = 0 ;
611
625
612
- pgss_store (queryString , INSTR_TIME_GET_DOUBLE (duration ), rows );
626
+ /* calc differences of buffer counters. */
627
+ bufusage .shared_blks_hit =
628
+ pgBufferUsage .shared_blks_hit - bufusage .shared_blks_hit ;
629
+ bufusage .shared_blks_read =
630
+ pgBufferUsage .shared_blks_read - bufusage .shared_blks_read ;
631
+ bufusage .shared_blks_written =
632
+ pgBufferUsage .shared_blks_written - bufusage .shared_blks_written ;
633
+ bufusage .local_blks_hit =
634
+ pgBufferUsage .local_blks_hit - bufusage .local_blks_hit ;
635
+ bufusage .local_blks_read =
636
+ pgBufferUsage .local_blks_read - bufusage .local_blks_read ;
637
+ bufusage .local_blks_written =
638
+ pgBufferUsage .local_blks_written - bufusage .local_blks_written ;
639
+ bufusage .temp_blks_read =
640
+ pgBufferUsage .temp_blks_read - bufusage .temp_blks_read ;
641
+ bufusage .temp_blks_written =
642
+ pgBufferUsage .temp_blks_written - bufusage .temp_blks_written ;
643
+
644
+ pgss_store (queryString , INSTR_TIME_GET_DOUBLE (duration ), rows ,
645
+ & bufusage );
613
646
}
614
647
else
615
648
{
@@ -660,7 +693,8 @@ pgss_match_fn(const void *key1, const void *key2, Size keysize)
660
693
* Store some statistics for a statement.
661
694
*/
662
695
static void
663
- pgss_store (const char * query , double total_time , uint64 rows )
696
+ pgss_store (const char * query , double total_time , uint64 rows ,
697
+ const BufferUsage * bufusage )
664
698
{
665
699
pgssHashKey key ;
666
700
double usage ;
@@ -706,6 +740,14 @@ pgss_store(const char *query, double total_time, uint64 rows)
706
740
e -> counters .calls += 1 ;
707
741
e -> counters .total_time += total_time ;
708
742
e -> counters .rows += rows ;
743
+ e -> counters .shared_blks_hit += bufusage -> shared_blks_hit ;
744
+ e -> counters .shared_blks_read += bufusage -> shared_blks_read ;
745
+ e -> counters .shared_blks_written += bufusage -> shared_blks_written ;
746
+ e -> counters .local_blks_hit += bufusage -> local_blks_hit ;
747
+ e -> counters .local_blks_read += bufusage -> local_blks_read ;
748
+ e -> counters .local_blks_written += bufusage -> local_blks_written ;
749
+ e -> counters .temp_blks_read += bufusage -> temp_blks_read ;
750
+ e -> counters .temp_blks_written += bufusage -> temp_blks_written ;
709
751
e -> counters .usage += usage ;
710
752
SpinLockRelease (& e -> mutex );
711
753
}
@@ -727,7 +769,7 @@ pg_stat_statements_reset(PG_FUNCTION_ARGS)
727
769
PG_RETURN_VOID ();
728
770
}
729
771
730
- #define PG_STAT_STATEMENTS_COLS 6
772
+ #define PG_STAT_STATEMENTS_COLS 14
731
773
732
774
/*
733
775
* Retrieve statement statistics.
@@ -761,23 +803,13 @@ pg_stat_statements(PG_FUNCTION_ARGS)
761
803
errmsg ("materialize mode required, but it is not " \
762
804
"allowed in this context" )));
763
805
806
+ /* Build a tuple descriptor for our result type */
807
+ if (get_call_result_type (fcinfo , NULL , & tupdesc ) != TYPEFUNC_COMPOSITE )
808
+ elog (ERROR , "return type must be a row type" );
809
+
764
810
per_query_ctx = rsinfo -> econtext -> ecxt_per_query_memory ;
765
811
oldcontext = MemoryContextSwitchTo (per_query_ctx );
766
812
767
- tupdesc = CreateTemplateTupleDesc (PG_STAT_STATEMENTS_COLS , false);
768
- TupleDescInitEntry (tupdesc , (AttrNumber ) 1 , "userid" ,
769
- OIDOID , -1 , 0 );
770
- TupleDescInitEntry (tupdesc , (AttrNumber ) 2 , "dbid" ,
771
- OIDOID , -1 , 0 );
772
- TupleDescInitEntry (tupdesc , (AttrNumber ) 3 , "query" ,
773
- TEXTOID , -1 , 0 );
774
- TupleDescInitEntry (tupdesc , (AttrNumber ) 4 , "calls" ,
775
- INT8OID , -1 , 0 );
776
- TupleDescInitEntry (tupdesc , (AttrNumber ) 5 , "total_time" ,
777
- FLOAT8OID , -1 , 0 );
778
- TupleDescInitEntry (tupdesc , (AttrNumber ) 6 , "rows" ,
779
- INT8OID , -1 , 0 );
780
-
781
813
tupstore = tuplestore_begin_heap (true, false, work_mem );
782
814
rsinfo -> returnMode = SFRM_Materialize ;
783
815
rsinfo -> setResult = tupstore ;
@@ -829,6 +861,14 @@ pg_stat_statements(PG_FUNCTION_ARGS)
829
861
values [i ++ ] = Int64GetDatumFast (tmp .calls );
830
862
values [i ++ ] = Float8GetDatumFast (tmp .total_time );
831
863
values [i ++ ] = Int64GetDatumFast (tmp .rows );
864
+ values [i ++ ] = Int64GetDatumFast (tmp .shared_blks_hit );
865
+ values [i ++ ] = Int64GetDatumFast (tmp .shared_blks_read );
866
+ values [i ++ ] = Int64GetDatumFast (tmp .shared_blks_written );
867
+ values [i ++ ] = Int64GetDatumFast (tmp .local_blks_hit );
868
+ values [i ++ ] = Int64GetDatumFast (tmp .local_blks_read );
869
+ values [i ++ ] = Int64GetDatumFast (tmp .local_blks_written );
870
+ values [i ++ ] = Int64GetDatumFast (tmp .temp_blks_read );
871
+ values [i ++ ] = Int64GetDatumFast (tmp .temp_blks_written );
832
872
833
873
Assert (i == PG_STAT_STATEMENTS_COLS );
834
874
0 commit comments