pg_stat_statements: Track I/O timing for temporary file blocks
authorMichael Paquier <[email protected]>
Fri, 8 Apr 2022 04:12:07 +0000 (13:12 +0900)
committerMichael Paquier <[email protected]>
Fri, 8 Apr 2022 04:12:07 +0000 (13:12 +0900)
This commit adds two new columns to pg_stat_statements, called
temp_blk_read_time and temp_blk_write_time.  Those columns respectively
show the time spent to read and write temporary file blocks on disk,
whose tracking has been added in efb0ef9.  This information is
available when track_io_timing is enabled, like blk_read_time and
blk_write_time.

pg_stat_statements is updated to version to 1.10 as an effect of the
newly-added columns.  Tests for the upgrade path 1.9->1.10 are added.

PGSS_FILE_HEADER is bumped for the new stats file format.

Author: Masahiko Sawada
Reviewed-by: Georgios Kokolatos, Melanie Plageman, Julien Rouhaud,
Ranier Vilela
Discussion: https://postgr.es/m/CAD21AoAJgotTeP83p6HiAGDhs_9Fw9pZ2J=_tYTsiO5Ob-V5GQ@mail.gmail.com

contrib/pg_stat_statements/Makefile
contrib/pg_stat_statements/expected/oldextversions.out
contrib/pg_stat_statements/pg_stat_statements--1.9--1.10.sql [new file with mode: 0644]
contrib/pg_stat_statements/pg_stat_statements.c
contrib/pg_stat_statements/pg_stat_statements.control
contrib/pg_stat_statements/sql/oldextversions.sql
doc/src/sgml/pgstatstatements.sgml

index 7fabd96f38d4fdf53587119c61aa542855e71132..edc40c8bbfb567f4f47f1c150e0126bc9b6d6085 100644 (file)
@@ -6,7 +6,8 @@ OBJS = \
        pg_stat_statements.o
 
 EXTENSION = pg_stat_statements
-DATA = pg_stat_statements--1.4.sql pg_stat_statements--1.8--1.9.sql \
+DATA = pg_stat_statements--1.4.sql \
+       pg_stat_statements--1.9--1.10.sql pg_stat_statements--1.8--1.9.sql \
        pg_stat_statements--1.7--1.8.sql pg_stat_statements--1.6--1.7.sql \
        pg_stat_statements--1.5--1.6.sql pg_stat_statements--1.4--1.5.sql \
        pg_stat_statements--1.3--1.4.sql pg_stat_statements--1.2--1.3.sql \
index f18c08838f57f6033bb33af2a7ae250f018fc732..2813eb16cbe929cf12e76d9c3d20940700d953aa 100644 (file)
@@ -136,4 +136,110 @@ SELECT pg_get_functiondef('pg_stat_statements_reset'::regproc);
  
 (1 row)
 
+-- New function pg_stat_statement_info, and new function
+-- and view for pg_stat_statements introduced in 1.9
+AlTER EXTENSION pg_stat_statements UPDATE TO '1.9';
+SELECT pg_get_functiondef('pg_stat_statements_info'::regproc);
+                                                   pg_get_functiondef                                                    
+-------------------------------------------------------------------------------------------------------------------------
+ CREATE OR REPLACE FUNCTION public.pg_stat_statements_info(OUT dealloc bigint, OUT stats_reset timestamp with time zone)+
+  RETURNS record                                                                                                        +
+  LANGUAGE c                                                                                                            +
+  PARALLEL SAFE STRICT                                                                                                  +
+ AS '$libdir/pg_stat_statements', $function$pg_stat_statements_info$function$                                           +
+(1 row)
+
+\d pg_stat_statements
+                    View "public.pg_stat_statements"
+       Column        |       Type       | Collation | Nullable | Default 
+---------------------+------------------+-----------+----------+---------
+ userid              | oid              |           |          | 
+ dbid                | oid              |           |          | 
+ toplevel            | boolean          |           |          | 
+ queryid             | bigint           |           |          | 
+ query               | text             |           |          | 
+ plans               | bigint           |           |          | 
+ total_plan_time     | double precision |           |          | 
+ min_plan_time       | double precision |           |          | 
+ max_plan_time       | double precision |           |          | 
+ mean_plan_time      | double precision |           |          | 
+ stddev_plan_time    | double precision |           |          | 
+ calls               | bigint           |           |          | 
+ total_exec_time     | double precision |           |          | 
+ min_exec_time       | double precision |           |          | 
+ max_exec_time       | double precision |           |          | 
+ mean_exec_time      | double precision |           |          | 
+ stddev_exec_time    | double precision |           |          | 
+ rows                | bigint           |           |          | 
+ shared_blks_hit     | bigint           |           |          | 
+ shared_blks_read    | bigint           |           |          | 
+ shared_blks_dirtied | bigint           |           |          | 
+ shared_blks_written | bigint           |           |          | 
+ local_blks_hit      | bigint           |           |          | 
+ local_blks_read     | bigint           |           |          | 
+ local_blks_dirtied  | bigint           |           |          | 
+ local_blks_written  | bigint           |           |          | 
+ temp_blks_read      | bigint           |           |          | 
+ temp_blks_written   | bigint           |           |          | 
+ blk_read_time       | double precision |           |          | 
+ blk_write_time      | double precision |           |          | 
+ wal_records         | bigint           |           |          | 
+ wal_fpi             | bigint           |           |          | 
+ wal_bytes           | numeric          |           |          | 
+
+SELECT count(*) > 0 AS has_data FROM pg_stat_statements;
+ has_data 
+----------
+ t
+(1 row)
+
+-- New functions and views for pg_stat_statements in 1.10
+AlTER EXTENSION pg_stat_statements UPDATE TO '1.10';
+\d pg_stat_statements
+                    View "public.pg_stat_statements"
+       Column        |       Type       | Collation | Nullable | Default 
+---------------------+------------------+-----------+----------+---------
+ userid              | oid              |           |          | 
+ dbid                | oid              |           |          | 
+ toplevel            | boolean          |           |          | 
+ queryid             | bigint           |           |          | 
+ query               | text             |           |          | 
+ plans               | bigint           |           |          | 
+ total_plan_time     | double precision |           |          | 
+ min_plan_time       | double precision |           |          | 
+ max_plan_time       | double precision |           |          | 
+ mean_plan_time      | double precision |           |          | 
+ stddev_plan_time    | double precision |           |          | 
+ calls               | bigint           |           |          | 
+ total_exec_time     | double precision |           |          | 
+ min_exec_time       | double precision |           |          | 
+ max_exec_time       | double precision |           |          | 
+ mean_exec_time      | double precision |           |          | 
+ stddev_exec_time    | double precision |           |          | 
+ rows                | bigint           |           |          | 
+ shared_blks_hit     | bigint           |           |          | 
+ shared_blks_read    | bigint           |           |          | 
+ shared_blks_dirtied | bigint           |           |          | 
+ shared_blks_written | bigint           |           |          | 
+ local_blks_hit      | bigint           |           |          | 
+ local_blks_read     | bigint           |           |          | 
+ local_blks_dirtied  | bigint           |           |          | 
+ local_blks_written  | bigint           |           |          | 
+ temp_blks_read      | bigint           |           |          | 
+ temp_blks_written   | bigint           |           |          | 
+ blk_read_time       | double precision |           |          | 
+ blk_write_time      | double precision |           |          | 
+ temp_blk_read_time  | double precision |           |          | 
+ temp_blk_write_time | double precision |           |          | 
+ wal_records         | bigint           |           |          | 
+ wal_fpi             | bigint           |           |          | 
+ wal_bytes           | numeric          |           |          | 
+
+SELECT count(*) > 0 AS has_data FROM pg_stat_statements;
+ has_data 
+----------
+ t
+(1 row)
+
 DROP EXTENSION pg_stat_statements;
diff --git a/contrib/pg_stat_statements/pg_stat_statements--1.9--1.10.sql b/contrib/pg_stat_statements/pg_stat_statements--1.9--1.10.sql
new file mode 100644 (file)
index 0000000..ca777f1
--- /dev/null
@@ -0,0 +1,59 @@
+/* contrib/pg_stat_statements/pg_stat_statements--1.9--1.10.sql */
+
+-- complain if script is sourced in psql, rather than via ALTER EXTENSION
+\echo Use "ALTER EXTENSION pg_stat_statements UPDATE TO '1.10'" to load this file. \quit
+
+/* First we have to remove them from the extension */
+ALTER EXTENSION pg_stat_statements DROP VIEW pg_stat_statements;
+ALTER EXTENSION pg_stat_statements DROP FUNCTION pg_stat_statements(boolean);
+
+/* Then we can drop them */
+DROP VIEW pg_stat_statements;
+DROP FUNCTION pg_stat_statements(boolean);
+
+/* Now redefine */
+CREATE FUNCTION pg_stat_statements(IN showtext boolean,
+    OUT userid oid,
+    OUT dbid oid,
+    OUT toplevel bool,
+    OUT queryid bigint,
+    OUT query text,
+    OUT plans int8,
+    OUT total_plan_time float8,
+    OUT min_plan_time float8,
+    OUT max_plan_time float8,
+    OUT mean_plan_time float8,
+    OUT stddev_plan_time float8,
+    OUT calls int8,
+    OUT total_exec_time float8,
+    OUT min_exec_time float8,
+    OUT max_exec_time float8,
+    OUT mean_exec_time float8,
+    OUT stddev_exec_time float8,
+    OUT rows int8,
+    OUT shared_blks_hit int8,
+    OUT shared_blks_read int8,
+    OUT shared_blks_dirtied int8,
+    OUT shared_blks_written int8,
+    OUT local_blks_hit int8,
+    OUT local_blks_read int8,
+    OUT local_blks_dirtied int8,
+    OUT local_blks_written int8,
+    OUT temp_blks_read int8,
+    OUT temp_blks_written int8,
+    OUT blk_read_time float8,
+    OUT blk_write_time float8,
+    OUT temp_blk_read_time float8,
+    OUT temp_blk_write_time float8,
+    OUT wal_records int8,
+    OUT wal_fpi int8,
+    OUT wal_bytes numeric
+)
+RETURNS SETOF record
+AS 'MODULE_PATHNAME', 'pg_stat_statements_1_10'
+LANGUAGE C STRICT VOLATILE PARALLEL SAFE;
+
+CREATE VIEW pg_stat_statements AS
+  SELECT * FROM pg_stat_statements(true);
+
+GRANT SELECT ON pg_stat_statements TO PUBLIC;
index 1d6049f2fd887c99e4825b518b98e3a2adf0f2a8..42ac001053d6f1c3e9fde09c88e2229a86a9d922 100644 (file)
@@ -83,7 +83,7 @@ PG_MODULE_MAGIC;
 #define PGSS_TEXT_FILE PG_STAT_TMP_DIR "/pgss_query_texts.stat"
 
 /* Magic number identifying the stats file format */
-static const uint32 PGSS_FILE_HEADER = 0x20201227;
+static const uint32 PGSS_FILE_HEADER = 0x20220408;
 
 /* PostgreSQL major version number, changes in which invalidate all entries */
 static const uint32 PGSS_PG_MAJOR_VERSION = PG_VERSION_NUM / 100;
@@ -116,7 +116,8 @@ typedef enum pgssVersion
        PGSS_V1_2,
        PGSS_V1_3,
        PGSS_V1_8,
-       PGSS_V1_9
+       PGSS_V1_9,
+       PGSS_V1_10
 } pgssVersion;
 
 typedef enum pgssStoreKind
@@ -178,8 +179,11 @@ typedef struct Counters
        int64           local_blks_written; /* # of local disk blocks written */
        int64           temp_blks_read; /* # of temp blocks read */
        int64           temp_blks_written;      /* # of temp blocks written */
-       double          blk_read_time;  /* time spent reading, in msec */
-       double          blk_write_time; /* time spent writing, in msec */
+       double          blk_read_time;  /* time spent reading blocks, in msec */
+       double          blk_write_time; /* time spent writing blocks, in msec */
+       double          temp_blk_read_time; /* time spent reading temp blocks, in msec */
+       double          temp_blk_write_time;    /* time spent writing temp blocks, in
+                                                                                * msec */
        double          usage;                  /* usage factor */
        int64           wal_records;    /* # of WAL records generated */
        int64           wal_fpi;                /* # of WAL full page images generated */
@@ -297,6 +301,7 @@ PG_FUNCTION_INFO_V1(pg_stat_statements_1_2);
 PG_FUNCTION_INFO_V1(pg_stat_statements_1_3);
 PG_FUNCTION_INFO_V1(pg_stat_statements_1_8);
 PG_FUNCTION_INFO_V1(pg_stat_statements_1_9);
+PG_FUNCTION_INFO_V1(pg_stat_statements_1_10);
 PG_FUNCTION_INFO_V1(pg_stat_statements);
 PG_FUNCTION_INFO_V1(pg_stat_statements_info);
 
@@ -1364,6 +1369,8 @@ pgss_store(const char *query, uint64 queryId,
                e->counters.temp_blks_written += bufusage->temp_blks_written;
                e->counters.blk_read_time += INSTR_TIME_GET_MILLISEC(bufusage->blk_read_time);
                e->counters.blk_write_time += INSTR_TIME_GET_MILLISEC(bufusage->blk_write_time);
+               e->counters.temp_blk_read_time += INSTR_TIME_GET_MILLISEC(bufusage->temp_blk_read_time);
+               e->counters.temp_blk_write_time += INSTR_TIME_GET_MILLISEC(bufusage->temp_blk_write_time);
                e->counters.usage += USAGE_EXEC(total_time);
                e->counters.wal_records += walusage->wal_records;
                e->counters.wal_fpi += walusage->wal_fpi;
@@ -1417,7 +1424,8 @@ pg_stat_statements_reset(PG_FUNCTION_ARGS)
 #define PG_STAT_STATEMENTS_COLS_V1_3   23
 #define PG_STAT_STATEMENTS_COLS_V1_8   32
 #define PG_STAT_STATEMENTS_COLS_V1_9   33
-#define PG_STAT_STATEMENTS_COLS                        33      /* maximum of above */
+#define PG_STAT_STATEMENTS_COLS_V1_10  35
+#define PG_STAT_STATEMENTS_COLS                        35      /* maximum of above */
 
 /*
  * Retrieve statement statistics.
@@ -1429,6 +1437,16 @@ pg_stat_statements_reset(PG_FUNCTION_ARGS)
  * expected API version is identified by embedding it in the C name of the
  * function.  Unfortunately we weren't bright enough to do that for 1.1.
  */
+Datum
+pg_stat_statements_1_10(PG_FUNCTION_ARGS)
+{
+       bool            showtext = PG_GETARG_BOOL(0);
+
+       pg_stat_statements_internal(fcinfo, PGSS_V1_10, showtext);
+
+       return (Datum) 0;
+}
+
 Datum
 pg_stat_statements_1_9(PG_FUNCTION_ARGS)
 {
@@ -1542,6 +1560,10 @@ pg_stat_statements_internal(FunctionCallInfo fcinfo,
                        if (api_version != PGSS_V1_9)
                                elog(ERROR, "incorrect number of output arguments");
                        break;
+               case PG_STAT_STATEMENTS_COLS_V1_10:
+                       if (api_version != PGSS_V1_10)
+                               elog(ERROR, "incorrect number of output arguments");
+                       break;
                default:
                        elog(ERROR, "incorrect number of output arguments");
        }
@@ -1742,6 +1764,11 @@ pg_stat_statements_internal(FunctionCallInfo fcinfo,
                        values[i++] = Float8GetDatumFast(tmp.blk_read_time);
                        values[i++] = Float8GetDatumFast(tmp.blk_write_time);
                }
+               if (api_version >= PGSS_V1_10)
+               {
+                       values[i++] = Float8GetDatumFast(tmp.temp_blk_read_time);
+                       values[i++] = Float8GetDatumFast(tmp.temp_blk_write_time);
+               }
                if (api_version >= PGSS_V1_8)
                {
                        char            buf[256];
@@ -1766,6 +1793,7 @@ pg_stat_statements_internal(FunctionCallInfo fcinfo,
                                         api_version == PGSS_V1_3 ? PG_STAT_STATEMENTS_COLS_V1_3 :
                                         api_version == PGSS_V1_8 ? PG_STAT_STATEMENTS_COLS_V1_8 :
                                         api_version == PGSS_V1_9 ? PG_STAT_STATEMENTS_COLS_V1_9 :
+                                        api_version == PGSS_V1_10 ? PG_STAT_STATEMENTS_COLS_V1_10 :
                                         -1 /* fail if you forget to update this assert */ ));
 
                tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls);
index 2f1ce6ed50705b64a62ba221b11c26cef4635592..0747e48138373377999693a1126a28b60e9aa92c 100644 (file)
@@ -1,5 +1,5 @@
 # pg_stat_statements extension
 comment = 'track planning and execution statistics of all SQL statements executed'
-default_version = '1.9'
+default_version = '1.10'
 module_pathname = '$libdir/pg_stat_statements'
 relocatable = true
index f2e822acd3e17d3ca19b0761a599cc9d5d387a30..e2a83106d4cec15f0078c02b9d3dbb653206773a 100644 (file)
@@ -36,4 +36,16 @@ AlTER EXTENSION pg_stat_statements UPDATE TO '1.8';
 \d pg_stat_statements
 SELECT pg_get_functiondef('pg_stat_statements_reset'::regproc);
 
+-- New function pg_stat_statement_info, and new function
+-- and view for pg_stat_statements introduced in 1.9
+AlTER EXTENSION pg_stat_statements UPDATE TO '1.9';
+SELECT pg_get_functiondef('pg_stat_statements_info'::regproc);
+\d pg_stat_statements
+SELECT count(*) > 0 AS has_data FROM pg_stat_statements;
+
+-- New functions and views for pg_stat_statements in 1.10
+AlTER EXTENSION pg_stat_statements UPDATE TO '1.10';
+\d pg_stat_statements
+SELECT count(*) > 0 AS has_data FROM pg_stat_statements;
+
 DROP EXTENSION pg_stat_statements;
index 3a7e36bd13c613299808dc42d0270f27c56bc9ec..0ead2464d874f54a4acc7d04d40146fb667e775b 100644 (file)
        <structfield>blk_read_time</structfield> <type>double precision</type>
       </para>
       <para>
-       Total time the statement spent reading blocks, in milliseconds
+       Total time the statement spent reading data file blocks, in milliseconds
        (if <xref linkend="guc-track-io-timing"/> is enabled, otherwise zero)
       </para></entry>
      </row>
        <structfield>blk_write_time</structfield> <type>double precision</type>
       </para>
       <para>
-       Total time the statement spent writing blocks, in milliseconds
+       Total time the statement spent writing data file blocks, in milliseconds
        (if <xref linkend="guc-track-io-timing"/> is enabled, otherwise zero)
       </para></entry>
      </row>
 
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>temp_blk_read_time</structfield> <type>double precision</type>
+      </para>
+      <para>
+       Total time the statement spent reading temporary file blocks, in
+       milliseconds (if <xref linkend="guc-track-io-timing"/> is enabled,
+       otherwise zero)
+      </para></entry>
+     </row>
+
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>temp_blk_write_time</structfield> <type>double precision</type>
+      </para>
+      <para>
+       Total time the statement spent writing temporary file blocks, in
+       milliseconds (if <xref linkend="guc-track-io-timing"/> is enabled,
+       otherwise zero)
+      </para></entry>
+     </row>
+
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
        <structfield>wal_records</structfield> <type>bigint</type>