Skip to content

Commit 5b4f346

Browse files
committed
Expose track_iotiming information via pg_stat_statements.
Ants Aasma, reviewed by Greg Smith, with very minor tweaks by me.
1 parent 5d3fcc4 commit 5b4f346

File tree

4 files changed

+57
-20
lines changed

4 files changed

+57
-20
lines changed

contrib/pg_stat_statements/pg_stat_statements--1.0--1.1.sql

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ CREATE FUNCTION pg_stat_statements(
2828
OUT local_blks_dirtied int8,
2929
OUT local_blks_written int8,
3030
OUT temp_blks_read int8,
31-
OUT temp_blks_written int8
31+
OUT temp_blks_written int8,
32+
OUT time_read float8,
33+
OUT time_write float8
3234
)
3335
RETURNS SETOF record
3436
AS 'MODULE_PATHNAME'

contrib/pg_stat_statements/pg_stat_statements--1.1.sql

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ CREATE FUNCTION pg_stat_statements(
2525
OUT local_blks_dirtied int8,
2626
OUT local_blks_written int8,
2727
OUT temp_blks_read int8,
28-
OUT temp_blks_written int8
28+
OUT temp_blks_written int8,
29+
OUT time_read float8,
30+
OUT time_write float8
2931
)
3032
RETURNS SETOF record
3133
AS 'MODULE_PATHNAME'

contrib/pg_stat_statements/pg_stat_statements.c

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ typedef struct Counters
8585
int64 local_blks_written; /* # of local disk blocks written */
8686
int64 temp_blks_read; /* # of temp blocks read */
8787
int64 temp_blks_written; /* # of temp blocks written */
88+
double time_read; /* time spent reading in seconds */
89+
double time_write; /* time spent writing in seconds */
8890
double usage; /* usage factor */
8991
} Counters;
9092

@@ -618,9 +620,9 @@ pgss_ProcessUtility(Node *parsetree, const char *queryString,
618620
instr_time start;
619621
instr_time duration;
620622
uint64 rows = 0;
621-
BufferUsage bufusage;
623+
BufferUsage bufusage_start, bufusage;
622624

623-
bufusage = pgBufferUsage;
625+
bufusage_start = pgBufferUsage;
624626
INSTR_TIME_SET_CURRENT(start);
625627

626628
nested_level++;
@@ -651,25 +653,29 @@ pgss_ProcessUtility(Node *parsetree, const char *queryString,
651653

652654
/* calc differences of buffer counters. */
653655
bufusage.shared_blks_hit =
654-
pgBufferUsage.shared_blks_hit - bufusage.shared_blks_hit;
656+
pgBufferUsage.shared_blks_hit - bufusage_start.shared_blks_hit;
655657
bufusage.shared_blks_read =
656-
pgBufferUsage.shared_blks_read - bufusage.shared_blks_read;
658+
pgBufferUsage.shared_blks_read - bufusage_start.shared_blks_read;
657659
bufusage.shared_blks_dirtied =
658-
pgBufferUsage.shared_blks_dirtied - bufusage.shared_blks_dirtied;
660+
pgBufferUsage.shared_blks_dirtied - bufusage_start.shared_blks_dirtied;
659661
bufusage.shared_blks_written =
660-
pgBufferUsage.shared_blks_written - bufusage.shared_blks_written;
662+
pgBufferUsage.shared_blks_written - bufusage_start.shared_blks_written;
661663
bufusage.local_blks_hit =
662-
pgBufferUsage.local_blks_hit - bufusage.local_blks_hit;
664+
pgBufferUsage.local_blks_hit - bufusage_start.local_blks_hit;
663665
bufusage.local_blks_read =
664-
pgBufferUsage.local_blks_read - bufusage.local_blks_read;
666+
pgBufferUsage.local_blks_read - bufusage_start.local_blks_read;
665667
bufusage.local_blks_dirtied =
666-
pgBufferUsage.local_blks_dirtied - bufusage.local_blks_dirtied;
668+
pgBufferUsage.local_blks_dirtied - bufusage_start.local_blks_dirtied;
667669
bufusage.local_blks_written =
668-
pgBufferUsage.local_blks_written - bufusage.local_blks_written;
670+
pgBufferUsage.local_blks_written - bufusage_start.local_blks_written;
669671
bufusage.temp_blks_read =
670-
pgBufferUsage.temp_blks_read - bufusage.temp_blks_read;
672+
pgBufferUsage.temp_blks_read - bufusage_start.temp_blks_read;
671673
bufusage.temp_blks_written =
672-
pgBufferUsage.temp_blks_written - bufusage.temp_blks_written;
674+
pgBufferUsage.temp_blks_written - bufusage_start.temp_blks_written;
675+
bufusage.time_read = pgBufferUsage.time_read;
676+
INSTR_TIME_SUBTRACT(bufusage.time_read, bufusage_start.time_read);
677+
bufusage.time_write = pgBufferUsage.time_write;
678+
INSTR_TIME_SUBTRACT(bufusage.time_write, bufusage_start.time_write);
673679

674680
pgss_store(queryString, INSTR_TIME_GET_DOUBLE(duration), rows,
675681
&bufusage);
@@ -780,6 +786,8 @@ pgss_store(const char *query, double total_time, uint64 rows,
780786
e->counters.local_blks_written += bufusage->local_blks_written;
781787
e->counters.temp_blks_read += bufusage->temp_blks_read;
782788
e->counters.temp_blks_written += bufusage->temp_blks_written;
789+
e->counters.time_read += INSTR_TIME_GET_DOUBLE(bufusage->time_read);
790+
e->counters.time_write += INSTR_TIME_GET_DOUBLE(bufusage->time_write);
783791
e->counters.usage += usage;
784792
SpinLockRelease(&e->mutex);
785793
}
@@ -802,7 +810,7 @@ pg_stat_statements_reset(PG_FUNCTION_ARGS)
802810
}
803811

804812
#define PG_STAT_STATEMENTS_COLS_V1_0 14
805-
#define PG_STAT_STATEMENTS_COLS 16
813+
#define PG_STAT_STATEMENTS_COLS 18
806814

807815
/*
808816
* Retrieve statement statistics.
@@ -819,7 +827,7 @@ pg_stat_statements(PG_FUNCTION_ARGS)
819827
bool is_superuser = superuser();
820828
HASH_SEQ_STATUS hash_seq;
821829
pgssEntry *entry;
822-
bool sql_supports_dirty_counters = true;
830+
bool sql_supports_v1_1_counters = true;
823831

824832
if (!pgss || !pgss_hash)
825833
ereport(ERROR,
@@ -841,7 +849,7 @@ pg_stat_statements(PG_FUNCTION_ARGS)
841849
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
842850
elog(ERROR, "return type must be a row type");
843851
if (tupdesc->natts == PG_STAT_STATEMENTS_COLS_V1_0)
844-
sql_supports_dirty_counters = false;
852+
sql_supports_v1_1_counters = false;
845853

846854
per_query_ctx = rsinfo->econtext->ecxt_per_query_memory;
847855
oldcontext = MemoryContextSwitchTo(per_query_ctx);
@@ -899,18 +907,23 @@ pg_stat_statements(PG_FUNCTION_ARGS)
899907
values[i++] = Int64GetDatumFast(tmp.rows);
900908
values[i++] = Int64GetDatumFast(tmp.shared_blks_hit);
901909
values[i++] = Int64GetDatumFast(tmp.shared_blks_read);
902-
if (sql_supports_dirty_counters)
910+
if (sql_supports_v1_1_counters)
903911
values[i++] = Int64GetDatumFast(tmp.shared_blks_dirtied);
904912
values[i++] = Int64GetDatumFast(tmp.shared_blks_written);
905913
values[i++] = Int64GetDatumFast(tmp.local_blks_hit);
906914
values[i++] = Int64GetDatumFast(tmp.local_blks_read);
907-
if (sql_supports_dirty_counters)
915+
if (sql_supports_v1_1_counters)
908916
values[i++] = Int64GetDatumFast(tmp.local_blks_dirtied);
909917
values[i++] = Int64GetDatumFast(tmp.local_blks_written);
910918
values[i++] = Int64GetDatumFast(tmp.temp_blks_read);
911919
values[i++] = Int64GetDatumFast(tmp.temp_blks_written);
920+
if (sql_supports_v1_1_counters)
921+
{
922+
values[i++] = Float8GetDatumFast(tmp.time_read);
923+
values[i++] = Float8GetDatumFast(tmp.time_write);
924+
}
912925

913-
Assert(i == sql_supports_dirty_counters ? \
926+
Assert(i == sql_supports_v1_1_counters ? \
914927
PG_STAT_STATEMENTS_COLS : PG_STAT_STATEMENTS_COLS_V1_0);
915928

916929
tuplestore_putvalues(tupstore, tupdesc, values, nulls);

doc/src/sgml/pgstatstatements.sgml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,26 @@
155155
<entry>Total number of temp blocks writes by the statement</entry>
156156
</row>
157157

158+
<row>
159+
<entry><structfield>time_read</structfield></entry>
160+
<entry><type>double precision</type></entry>
161+
<entry></entry>
162+
<entry>
163+
Total time the statement spent reading blocks, in seconds
164+
(if <xref linkend="guc-track-iotiming"> is enabled, otherwise zero)
165+
</entry>
166+
</row>
167+
168+
<row>
169+
<entry><structfield>time_write</structfield></entry>
170+
<entry><type>double precision</type></entry>
171+
<entry></entry>
172+
<entry>
173+
Total time the statement spent writing blocks, in seconds
174+
(if <xref linkend="guc-track-iotiming"> is enabled, otherwise zero)
175+
</entry>
176+
</row>
177+
158178
</tbody>
159179
</tgroup>
160180
</table>

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy