Track statement entry timestamp in contrib/pg_stat_statements
This patch adds 'stats_since' and 'minmax_stats_since' columns to the pg_stat_statements view and pg_stat_statements() function. The new min/max reset mode for the pg_stat_stetments_reset() function is controlled by the parameter minmax_only. 'stat_since' column is populated with the current timestamp when a new statement is added to the pg_stat_statements hashtable. It provides clean information about statistics collection time intervals for each statement. Besides it can be used by sampling solutions to detect situations when a statement was evicted and stored again between samples. Such a sampling solution could derive any pg_stat_statements statistic values for an interval between two samples with the exception of all min/max statistics. To address this issue this patch adds the ability to reset min/max statistics independently of the statement reset using the new minmax_only parameter of the pg_stat_statements_reset(userid oid, dbid oid, queryid bigint, minmax_only boolean) function. The timestamp of such reset is stored in the minmax_stats_since field for each statement. pg_stat_statements_reset() function now returns the timestamp of a reset as the result. Discussion: https://postgr.es/m/flat/72e80e7b160a6eb189df9ef6f068cce3765d37f8.camel%40moonset.ru Author: Andrei Zubkov Reviewed-by: Julien Rouhaud, Hayato Kuroda, Yuki Seino, Chengxi Sun Reviewed-by: Anton Melnikov, Darren Rush, Michael Paquier, Sergei Kornilov Reviewed-by: Alena Rybakina, Andrei Lepikhov
This commit is contained in:
parent
6ab1dbd26b
commit
dc9f8a7983
@ -19,7 +19,7 @@ LDFLAGS_SL += $(filter -lm, $(LIBS))
|
|||||||
|
|
||||||
REGRESS_OPTS = --temp-config $(top_srcdir)/contrib/pg_stat_statements/pg_stat_statements.conf
|
REGRESS_OPTS = --temp-config $(top_srcdir)/contrib/pg_stat_statements/pg_stat_statements.conf
|
||||||
REGRESS = select dml cursors utility level_tracking planning \
|
REGRESS = select dml cursors utility level_tracking planning \
|
||||||
user_activity wal cleanup oldextversions
|
user_activity wal entry_timestamp cleanup oldextversions
|
||||||
# Disabled because these tests require "shared_preload_libraries=pg_stat_statements",
|
# Disabled because these tests require "shared_preload_libraries=pg_stat_statements",
|
||||||
# which typical installcheck users do not have (e.g. buildfarm clients).
|
# which typical installcheck users do not have (e.g. buildfarm clients).
|
||||||
NO_INSTALLCHECK = 1
|
NO_INSTALLCHECK = 1
|
||||||
|
159
contrib/pg_stat_statements/expected/entry_timestamp.out
Normal file
159
contrib/pg_stat_statements/expected/entry_timestamp.out
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
--
|
||||||
|
-- statement timestamps
|
||||||
|
--
|
||||||
|
-- planning time is needed during tests
|
||||||
|
SET pg_stat_statements.track_planning = TRUE;
|
||||||
|
SELECT 1 AS "STMTTS1";
|
||||||
|
STMTTS1
|
||||||
|
---------
|
||||||
|
1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT now() AS ref_ts \gset
|
||||||
|
SELECT 1,2 AS "STMTTS2";
|
||||||
|
?column? | STMTTS2
|
||||||
|
----------+---------
|
||||||
|
1 | 2
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT stats_since >= :'ref_ts', count(*) FROM pg_stat_statements
|
||||||
|
WHERE query LIKE '%STMTTS%'
|
||||||
|
GROUP BY stats_since >= :'ref_ts'
|
||||||
|
ORDER BY stats_since >= :'ref_ts';
|
||||||
|
?column? | count
|
||||||
|
----------+-------
|
||||||
|
f | 1
|
||||||
|
t | 1
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
SELECT now() AS ref_ts \gset
|
||||||
|
SELECT
|
||||||
|
count(*) as total,
|
||||||
|
count(*) FILTER (
|
||||||
|
WHERE min_plan_time + max_plan_time = 0
|
||||||
|
) as minmax_plan_zero,
|
||||||
|
count(*) FILTER (
|
||||||
|
WHERE min_exec_time + max_exec_time = 0
|
||||||
|
) as minmax_exec_zero,
|
||||||
|
count(*) FILTER (
|
||||||
|
WHERE minmax_stats_since >= :'ref_ts'
|
||||||
|
) as minmax_stats_since_after_ref,
|
||||||
|
count(*) FILTER (
|
||||||
|
WHERE stats_since >= :'ref_ts'
|
||||||
|
) as stats_since_after_ref
|
||||||
|
FROM pg_stat_statements
|
||||||
|
WHERE query LIKE '%STMTTS%';
|
||||||
|
total | minmax_plan_zero | minmax_exec_zero | minmax_stats_since_after_ref | stats_since_after_ref
|
||||||
|
-------+------------------+------------------+------------------------------+-----------------------
|
||||||
|
2 | 0 | 0 | 0 | 0
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- Perform single min/max reset
|
||||||
|
SELECT pg_stat_statements_reset(0, 0, queryid, true) AS minmax_reset_ts
|
||||||
|
FROM pg_stat_statements
|
||||||
|
WHERE query LIKE '%STMTTS1%' \gset
|
||||||
|
-- check
|
||||||
|
SELECT
|
||||||
|
count(*) as total,
|
||||||
|
count(*) FILTER (
|
||||||
|
WHERE min_plan_time + max_plan_time = 0
|
||||||
|
) as minmax_plan_zero,
|
||||||
|
count(*) FILTER (
|
||||||
|
WHERE min_exec_time + max_exec_time = 0
|
||||||
|
) as minmax_exec_zero,
|
||||||
|
count(*) FILTER (
|
||||||
|
WHERE minmax_stats_since >= :'ref_ts'
|
||||||
|
) as minmax_stats_since_after_ref,
|
||||||
|
count(*) FILTER (
|
||||||
|
WHERE stats_since >= :'ref_ts'
|
||||||
|
) as stats_since_after_ref
|
||||||
|
FROM pg_stat_statements
|
||||||
|
WHERE query LIKE '%STMTTS%';
|
||||||
|
total | minmax_plan_zero | minmax_exec_zero | minmax_stats_since_after_ref | stats_since_after_ref
|
||||||
|
-------+------------------+------------------+------------------------------+-----------------------
|
||||||
|
2 | 1 | 1 | 1 | 0
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- check minmax reset timestamps
|
||||||
|
SELECT
|
||||||
|
query, minmax_stats_since = :'minmax_reset_ts' AS reset_ts_match
|
||||||
|
FROM pg_stat_statements
|
||||||
|
WHERE query LIKE '%STMTTS%'
|
||||||
|
ORDER BY query COLLATE "C";
|
||||||
|
query | reset_ts_match
|
||||||
|
---------------------------+----------------
|
||||||
|
SELECT $1 AS "STMTTS1" | t
|
||||||
|
SELECT $1,$2 AS "STMTTS2" | f
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
-- check that minmax reset does not set stats_reset
|
||||||
|
SELECT
|
||||||
|
stats_reset = :'minmax_reset_ts' AS stats_reset_ts_match
|
||||||
|
FROM pg_stat_statements_info;
|
||||||
|
stats_reset_ts_match
|
||||||
|
----------------------
|
||||||
|
f
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- Perform common min/max reset
|
||||||
|
SELECT pg_stat_statements_reset(0, 0, 0, true) AS minmax_reset_ts \gset
|
||||||
|
-- check again
|
||||||
|
SELECT
|
||||||
|
count(*) as total,
|
||||||
|
count(*) FILTER (
|
||||||
|
WHERE min_plan_time + max_plan_time = 0
|
||||||
|
) as minmax_plan_zero,
|
||||||
|
count(*) FILTER (
|
||||||
|
WHERE min_exec_time + max_exec_time = 0
|
||||||
|
) as minmax_exec_zero,
|
||||||
|
count(*) FILTER (
|
||||||
|
WHERE minmax_stats_since >= :'ref_ts'
|
||||||
|
) as minmax_ts_after_ref,
|
||||||
|
count(*) FILTER (
|
||||||
|
WHERE minmax_stats_since = :'minmax_reset_ts'
|
||||||
|
) as minmax_ts_match,
|
||||||
|
count(*) FILTER (
|
||||||
|
WHERE stats_since >= :'ref_ts'
|
||||||
|
) as stats_since_after_ref
|
||||||
|
FROM pg_stat_statements
|
||||||
|
WHERE query LIKE '%STMTTS%';
|
||||||
|
total | minmax_plan_zero | minmax_exec_zero | minmax_ts_after_ref | minmax_ts_match | stats_since_after_ref
|
||||||
|
-------+------------------+------------------+---------------------+-----------------+-----------------------
|
||||||
|
2 | 2 | 2 | 2 | 2 | 0
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- Execute first query once more to check stats update
|
||||||
|
SELECT 1 AS "STMTTS1";
|
||||||
|
STMTTS1
|
||||||
|
---------
|
||||||
|
1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- check
|
||||||
|
-- we don't check planing times here to be independent of
|
||||||
|
-- plan caching approach
|
||||||
|
SELECT
|
||||||
|
count(*) as total,
|
||||||
|
count(*) FILTER (
|
||||||
|
WHERE min_exec_time + max_exec_time = 0
|
||||||
|
) as minmax_exec_zero,
|
||||||
|
count(*) FILTER (
|
||||||
|
WHERE minmax_stats_since >= :'ref_ts'
|
||||||
|
) as minmax_ts_after_ref,
|
||||||
|
count(*) FILTER (
|
||||||
|
WHERE stats_since >= :'ref_ts'
|
||||||
|
) as stats_since_after_ref
|
||||||
|
FROM pg_stat_statements
|
||||||
|
WHERE query LIKE '%STMTTS%';
|
||||||
|
total | minmax_exec_zero | minmax_ts_after_ref | stats_since_after_ref
|
||||||
|
-------+------------------+---------------------+-----------------------
|
||||||
|
2 | 1 | 2 | 0
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- Cleanup
|
||||||
|
SELECT pg_stat_statements_reset() IS NOT NULL AS t;
|
||||||
|
t
|
||||||
|
---
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
@ -250,12 +250,12 @@ SELECT count(*) > 0 AS has_data FROM pg_stat_statements;
|
|||||||
t
|
t
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- New views for pg_stat_statements in 1.11
|
-- New functions and views for pg_stat_statements in 1.11
|
||||||
AlTER EXTENSION pg_stat_statements UPDATE TO '1.11';
|
AlTER EXTENSION pg_stat_statements UPDATE TO '1.11';
|
||||||
\d pg_stat_statements
|
\d pg_stat_statements
|
||||||
View "public.pg_stat_statements"
|
View "public.pg_stat_statements"
|
||||||
Column | Type | Collation | Nullable | Default
|
Column | Type | Collation | Nullable | Default
|
||||||
------------------------+------------------+-----------+----------+---------
|
------------------------+--------------------------+-----------+----------+---------
|
||||||
userid | oid | | |
|
userid | oid | | |
|
||||||
dbid | oid | | |
|
dbid | oid | | |
|
||||||
toplevel | boolean | | |
|
toplevel | boolean | | |
|
||||||
@ -303,6 +303,8 @@ AlTER EXTENSION pg_stat_statements UPDATE TO '1.11';
|
|||||||
jit_emission_time | double precision | | |
|
jit_emission_time | double precision | | |
|
||||||
jit_deform_count | bigint | | |
|
jit_deform_count | bigint | | |
|
||||||
jit_deform_time | double precision | | |
|
jit_deform_time | double precision | | |
|
||||||
|
stats_since | timestamp with time zone | | |
|
||||||
|
minmax_stats_since | timestamp with time zone | | |
|
||||||
|
|
||||||
SELECT count(*) > 0 AS has_data FROM pg_stat_statements;
|
SELECT count(*) > 0 AS has_data FROM pg_stat_statements;
|
||||||
has_data
|
has_data
|
||||||
@ -310,4 +312,16 @@ SELECT count(*) > 0 AS has_data FROM pg_stat_statements;
|
|||||||
t
|
t
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
-- New parameter minmax_only of pg_stat_statements_reset function
|
||||||
|
SELECT pg_get_functiondef('pg_stat_statements_reset'::regproc);
|
||||||
|
pg_get_functiondef
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
CREATE OR REPLACE FUNCTION public.pg_stat_statements_reset(userid oid DEFAULT 0, dbid oid DEFAULT 0, queryid bigint DEFAULT 0, minmax_only boolean DEFAULT false)+
|
||||||
|
RETURNS timestamp with time zone +
|
||||||
|
LANGUAGE c +
|
||||||
|
PARALLEL SAFE STRICT +
|
||||||
|
AS '$libdir/pg_stat_statements', $function$pg_stat_statements_reset_1_11$function$ +
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
DROP EXTENSION pg_stat_statements;
|
DROP EXTENSION pg_stat_statements;
|
||||||
|
@ -49,6 +49,7 @@ tests += {
|
|||||||
'planning',
|
'planning',
|
||||||
'user_activity',
|
'user_activity',
|
||||||
'wal',
|
'wal',
|
||||||
|
'entry_timestamp',
|
||||||
'cleanup',
|
'cleanup',
|
||||||
'oldextversions',
|
'oldextversions',
|
||||||
],
|
],
|
||||||
|
@ -3,13 +3,10 @@
|
|||||||
-- complain if script is sourced in psql, rather than via ALTER EXTENSION
|
-- complain if script is sourced in psql, rather than via ALTER EXTENSION
|
||||||
\echo Use "ALTER EXTENSION pg_stat_statements UPDATE TO '1.11'" to load this file. \quit
|
\echo Use "ALTER EXTENSION pg_stat_statements UPDATE TO '1.11'" to load this file. \quit
|
||||||
|
|
||||||
/* First we have to remove them from the extension */
|
/* Drop old versions */
|
||||||
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 VIEW pg_stat_statements;
|
||||||
DROP FUNCTION pg_stat_statements(boolean);
|
DROP FUNCTION pg_stat_statements(boolean);
|
||||||
|
DROP FUNCTION pg_stat_statements_reset(Oid, Oid, bigint);
|
||||||
|
|
||||||
/* Now redefine */
|
/* Now redefine */
|
||||||
CREATE FUNCTION pg_stat_statements(IN showtext boolean,
|
CREATE FUNCTION pg_stat_statements(IN showtext boolean,
|
||||||
@ -59,7 +56,9 @@ CREATE FUNCTION pg_stat_statements(IN showtext boolean,
|
|||||||
OUT jit_emission_count int8,
|
OUT jit_emission_count int8,
|
||||||
OUT jit_emission_time float8,
|
OUT jit_emission_time float8,
|
||||||
OUT jit_deform_count int8,
|
OUT jit_deform_count int8,
|
||||||
OUT jit_deform_time float8
|
OUT jit_deform_time float8,
|
||||||
|
OUT stats_since timestamp with time zone,
|
||||||
|
OUT minmax_stats_since timestamp with time zone
|
||||||
)
|
)
|
||||||
RETURNS SETOF record
|
RETURNS SETOF record
|
||||||
AS 'MODULE_PATHNAME', 'pg_stat_statements_1_11'
|
AS 'MODULE_PATHNAME', 'pg_stat_statements_1_11'
|
||||||
@ -69,3 +68,15 @@ CREATE VIEW pg_stat_statements AS
|
|||||||
SELECT * FROM pg_stat_statements(true);
|
SELECT * FROM pg_stat_statements(true);
|
||||||
|
|
||||||
GRANT SELECT ON pg_stat_statements TO PUBLIC;
|
GRANT SELECT ON pg_stat_statements TO PUBLIC;
|
||||||
|
|
||||||
|
CREATE FUNCTION pg_stat_statements_reset(IN userid Oid DEFAULT 0,
|
||||||
|
IN dbid Oid DEFAULT 0,
|
||||||
|
IN queryid bigint DEFAULT 0,
|
||||||
|
IN minmax_only boolean DEFAULT false
|
||||||
|
)
|
||||||
|
RETURNS timestamp with time zone
|
||||||
|
AS 'MODULE_PATHNAME', 'pg_stat_statements_reset_1_11'
|
||||||
|
LANGUAGE C STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
-- Don't want this to be available to non-superusers.
|
||||||
|
REVOKE ALL ON FUNCTION pg_stat_statements_reset(Oid, Oid, bigint, boolean) FROM PUBLIC;
|
||||||
|
@ -155,9 +155,9 @@ typedef struct Counters
|
|||||||
double total_time[PGSS_NUMKIND]; /* total planning/execution time,
|
double total_time[PGSS_NUMKIND]; /* total planning/execution time,
|
||||||
* in msec */
|
* in msec */
|
||||||
double min_time[PGSS_NUMKIND]; /* minimum planning/execution time in
|
double min_time[PGSS_NUMKIND]; /* minimum planning/execution time in
|
||||||
* msec */
|
* msec since min/max reset */
|
||||||
double max_time[PGSS_NUMKIND]; /* maximum planning/execution time in
|
double max_time[PGSS_NUMKIND]; /* maximum planning/execution time in
|
||||||
* msec */
|
* msec since min/max reset */
|
||||||
double mean_time[PGSS_NUMKIND]; /* mean planning/execution time in
|
double mean_time[PGSS_NUMKIND]; /* mean planning/execution time in
|
||||||
* msec */
|
* msec */
|
||||||
double sum_var_time[PGSS_NUMKIND]; /* sum of variances in
|
double sum_var_time[PGSS_NUMKIND]; /* sum of variances in
|
||||||
@ -228,6 +228,8 @@ typedef struct pgssEntry
|
|||||||
Size query_offset; /* query text offset in external file */
|
Size query_offset; /* query text offset in external file */
|
||||||
int query_len; /* # of valid bytes in query string, or -1 */
|
int query_len; /* # of valid bytes in query string, or -1 */
|
||||||
int encoding; /* query text encoding */
|
int encoding; /* query text encoding */
|
||||||
|
TimestampTz stats_since; /* timestamp of entry allocation */
|
||||||
|
TimestampTz minmax_stats_since; /* timestamp of last min/max values reset */
|
||||||
slock_t mutex; /* protects the counters only */
|
slock_t mutex; /* protects the counters only */
|
||||||
} pgssEntry;
|
} pgssEntry;
|
||||||
|
|
||||||
@ -308,6 +310,7 @@ static bool pgss_save = true; /* whether to save stats across shutdown */
|
|||||||
|
|
||||||
PG_FUNCTION_INFO_V1(pg_stat_statements_reset);
|
PG_FUNCTION_INFO_V1(pg_stat_statements_reset);
|
||||||
PG_FUNCTION_INFO_V1(pg_stat_statements_reset_1_7);
|
PG_FUNCTION_INFO_V1(pg_stat_statements_reset_1_7);
|
||||||
|
PG_FUNCTION_INFO_V1(pg_stat_statements_reset_1_11);
|
||||||
PG_FUNCTION_INFO_V1(pg_stat_statements_1_2);
|
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_3);
|
||||||
PG_FUNCTION_INFO_V1(pg_stat_statements_1_8);
|
PG_FUNCTION_INFO_V1(pg_stat_statements_1_8);
|
||||||
@ -359,7 +362,7 @@ static char *qtext_fetch(Size query_offset, int query_len,
|
|||||||
char *buffer, Size buffer_size);
|
char *buffer, Size buffer_size);
|
||||||
static bool need_gc_qtexts(void);
|
static bool need_gc_qtexts(void);
|
||||||
static void gc_qtexts(void);
|
static void gc_qtexts(void);
|
||||||
static void entry_reset(Oid userid, Oid dbid, uint64 queryid);
|
static TimestampTz entry_reset(Oid userid, Oid dbid, uint64 queryid, bool minmax_only);
|
||||||
static char *generate_normalized_query(JumbleState *jstate, const char *query,
|
static char *generate_normalized_query(JumbleState *jstate, const char *query,
|
||||||
int query_loc, int *query_len_p);
|
int query_loc, int *query_len_p);
|
||||||
static void fill_in_constant_lengths(JumbleState *jstate, const char *query,
|
static void fill_in_constant_lengths(JumbleState *jstate, const char *query,
|
||||||
@ -654,6 +657,8 @@ pgss_shmem_startup(void)
|
|||||||
|
|
||||||
/* copy in the actual stats */
|
/* copy in the actual stats */
|
||||||
entry->counters = temp.counters;
|
entry->counters = temp.counters;
|
||||||
|
entry->stats_since = temp.stats_since;
|
||||||
|
entry->minmax_stats_since = temp.minmax_stats_since;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read global statistics for pg_stat_statements */
|
/* Read global statistics for pg_stat_statements */
|
||||||
@ -1416,12 +1421,24 @@ pgss_store(const char *query, uint64 queryId,
|
|||||||
e->counters.sum_var_time[kind] +=
|
e->counters.sum_var_time[kind] +=
|
||||||
(total_time - old_mean) * (total_time - e->counters.mean_time[kind]);
|
(total_time - old_mean) * (total_time - e->counters.mean_time[kind]);
|
||||||
|
|
||||||
/* calculate min and max time */
|
/*
|
||||||
|
* Calculate min and max time. min = 0 and max = 0 means that the
|
||||||
|
* min/max statistics were reset
|
||||||
|
*/
|
||||||
|
if (e->counters.min_time[kind] == 0
|
||||||
|
&& e->counters.max_time[kind] == 0)
|
||||||
|
{
|
||||||
|
e->counters.min_time[kind] = total_time;
|
||||||
|
e->counters.max_time[kind] = total_time;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (e->counters.min_time[kind] > total_time)
|
if (e->counters.min_time[kind] > total_time)
|
||||||
e->counters.min_time[kind] = total_time;
|
e->counters.min_time[kind] = total_time;
|
||||||
if (e->counters.max_time[kind] < total_time)
|
if (e->counters.max_time[kind] < total_time)
|
||||||
e->counters.max_time[kind] = total_time;
|
e->counters.max_time[kind] = total_time;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
e->counters.rows += rows;
|
e->counters.rows += rows;
|
||||||
e->counters.shared_blks_hit += bufusage->shared_blks_hit;
|
e->counters.shared_blks_hit += bufusage->shared_blks_hit;
|
||||||
e->counters.shared_blks_read += bufusage->shared_blks_read;
|
e->counters.shared_blks_read += bufusage->shared_blks_read;
|
||||||
@ -1490,18 +1507,34 @@ pg_stat_statements_reset_1_7(PG_FUNCTION_ARGS)
|
|||||||
dbid = PG_GETARG_OID(1);
|
dbid = PG_GETARG_OID(1);
|
||||||
queryid = (uint64) PG_GETARG_INT64(2);
|
queryid = (uint64) PG_GETARG_INT64(2);
|
||||||
|
|
||||||
entry_reset(userid, dbid, queryid);
|
entry_reset(userid, dbid, queryid, false);
|
||||||
|
|
||||||
PG_RETURN_VOID();
|
PG_RETURN_VOID();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Datum
|
||||||
|
pg_stat_statements_reset_1_11(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
Oid userid;
|
||||||
|
Oid dbid;
|
||||||
|
uint64 queryid;
|
||||||
|
bool minmax_only;
|
||||||
|
|
||||||
|
userid = PG_GETARG_OID(0);
|
||||||
|
dbid = PG_GETARG_OID(1);
|
||||||
|
queryid = (uint64) PG_GETARG_INT64(2);
|
||||||
|
minmax_only = PG_GETARG_BOOL(3);
|
||||||
|
|
||||||
|
PG_RETURN_TIMESTAMPTZ(entry_reset(userid, dbid, queryid, minmax_only));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reset statement statistics.
|
* Reset statement statistics.
|
||||||
*/
|
*/
|
||||||
Datum
|
Datum
|
||||||
pg_stat_statements_reset(PG_FUNCTION_ARGS)
|
pg_stat_statements_reset(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
entry_reset(0, 0, 0);
|
entry_reset(0, 0, 0, false);
|
||||||
|
|
||||||
PG_RETURN_VOID();
|
PG_RETURN_VOID();
|
||||||
}
|
}
|
||||||
@ -1514,8 +1547,8 @@ pg_stat_statements_reset(PG_FUNCTION_ARGS)
|
|||||||
#define PG_STAT_STATEMENTS_COLS_V1_8 32
|
#define PG_STAT_STATEMENTS_COLS_V1_8 32
|
||||||
#define PG_STAT_STATEMENTS_COLS_V1_9 33
|
#define PG_STAT_STATEMENTS_COLS_V1_9 33
|
||||||
#define PG_STAT_STATEMENTS_COLS_V1_10 43
|
#define PG_STAT_STATEMENTS_COLS_V1_10 43
|
||||||
#define PG_STAT_STATEMENTS_COLS_V1_11 47
|
#define PG_STAT_STATEMENTS_COLS_V1_11 49
|
||||||
#define PG_STAT_STATEMENTS_COLS 47 /* maximum of above */
|
#define PG_STAT_STATEMENTS_COLS 49 /* maximum of above */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Retrieve statement statistics.
|
* Retrieve statement statistics.
|
||||||
@ -1748,6 +1781,8 @@ pg_stat_statements_internal(FunctionCallInfo fcinfo,
|
|||||||
Counters tmp;
|
Counters tmp;
|
||||||
double stddev;
|
double stddev;
|
||||||
int64 queryid = entry->key.queryid;
|
int64 queryid = entry->key.queryid;
|
||||||
|
TimestampTz stats_since;
|
||||||
|
TimestampTz minmax_stats_since;
|
||||||
|
|
||||||
memset(values, 0, sizeof(values));
|
memset(values, 0, sizeof(values));
|
||||||
memset(nulls, 0, sizeof(nulls));
|
memset(nulls, 0, sizeof(nulls));
|
||||||
@ -1816,6 +1851,8 @@ pg_stat_statements_internal(FunctionCallInfo fcinfo,
|
|||||||
|
|
||||||
SpinLockAcquire(&e->mutex);
|
SpinLockAcquire(&e->mutex);
|
||||||
tmp = e->counters;
|
tmp = e->counters;
|
||||||
|
stats_since = e->stats_since;
|
||||||
|
minmax_stats_since = e->minmax_stats_since;
|
||||||
SpinLockRelease(&e->mutex);
|
SpinLockRelease(&e->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1912,6 +1949,8 @@ pg_stat_statements_internal(FunctionCallInfo fcinfo,
|
|||||||
{
|
{
|
||||||
values[i++] = Int64GetDatumFast(tmp.jit_deform_count);
|
values[i++] = Int64GetDatumFast(tmp.jit_deform_count);
|
||||||
values[i++] = Float8GetDatumFast(tmp.jit_deform_time);
|
values[i++] = Float8GetDatumFast(tmp.jit_deform_time);
|
||||||
|
values[i++] = TimestampTzGetDatum(stats_since);
|
||||||
|
values[i++] = TimestampTzGetDatum(minmax_stats_since);
|
||||||
}
|
}
|
||||||
|
|
||||||
Assert(i == (api_version == PGSS_V1_0 ? PG_STAT_STATEMENTS_COLS_V1_0 :
|
Assert(i == (api_version == PGSS_V1_0 ? PG_STAT_STATEMENTS_COLS_V1_0 :
|
||||||
@ -2030,6 +2069,8 @@ entry_alloc(pgssHashKey *key, Size query_offset, int query_len, int encoding,
|
|||||||
entry->query_offset = query_offset;
|
entry->query_offset = query_offset;
|
||||||
entry->query_len = query_len;
|
entry->query_len = query_len;
|
||||||
entry->encoding = encoding;
|
entry->encoding = encoding;
|
||||||
|
entry->stats_since = GetCurrentTimestamp();
|
||||||
|
entry->minmax_stats_since = entry->stats_since;
|
||||||
}
|
}
|
||||||
|
|
||||||
return entry;
|
return entry;
|
||||||
@ -2593,11 +2634,30 @@ gc_fail:
|
|||||||
record_gc_qtexts();
|
record_gc_qtexts();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define SINGLE_ENTRY_RESET(e) \
|
||||||
|
if (e) { \
|
||||||
|
if (minmax_only) { \
|
||||||
|
/* When requested reset only min/max statistics of an entry */ \
|
||||||
|
for (int kind = 0; kind < PGSS_NUMKIND; kind++) \
|
||||||
|
{ \
|
||||||
|
e->counters.max_time[kind] = 0; \
|
||||||
|
e->counters.min_time[kind] = 0; \
|
||||||
|
} \
|
||||||
|
e->minmax_stats_since = stats_reset; \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
/* Remove the key otherwise */ \
|
||||||
|
hash_search(pgss_hash, &e->key, HASH_REMOVE, NULL); \
|
||||||
|
num_remove++; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Release entries corresponding to parameters passed.
|
* Reset entries corresponding to parameters passed.
|
||||||
*/
|
*/
|
||||||
static void
|
static TimestampTz
|
||||||
entry_reset(Oid userid, Oid dbid, uint64 queryid)
|
entry_reset(Oid userid, Oid dbid, uint64 queryid, bool minmax_only)
|
||||||
{
|
{
|
||||||
HASH_SEQ_STATUS hash_seq;
|
HASH_SEQ_STATUS hash_seq;
|
||||||
pgssEntry *entry;
|
pgssEntry *entry;
|
||||||
@ -2605,6 +2665,7 @@ entry_reset(Oid userid, Oid dbid, uint64 queryid)
|
|||||||
long num_entries;
|
long num_entries;
|
||||||
long num_remove = 0;
|
long num_remove = 0;
|
||||||
pgssHashKey key;
|
pgssHashKey key;
|
||||||
|
TimestampTz stats_reset;
|
||||||
|
|
||||||
if (!pgss || !pgss_hash)
|
if (!pgss || !pgss_hash)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
@ -2614,6 +2675,8 @@ entry_reset(Oid userid, Oid dbid, uint64 queryid)
|
|||||||
LWLockAcquire(pgss->lock, LW_EXCLUSIVE);
|
LWLockAcquire(pgss->lock, LW_EXCLUSIVE);
|
||||||
num_entries = hash_get_num_entries(pgss_hash);
|
num_entries = hash_get_num_entries(pgss_hash);
|
||||||
|
|
||||||
|
stats_reset = GetCurrentTimestamp();
|
||||||
|
|
||||||
if (userid != 0 && dbid != 0 && queryid != UINT64CONST(0))
|
if (userid != 0 && dbid != 0 && queryid != UINT64CONST(0))
|
||||||
{
|
{
|
||||||
/* If all the parameters are available, use the fast path. */
|
/* If all the parameters are available, use the fast path. */
|
||||||
@ -2623,22 +2686,23 @@ entry_reset(Oid userid, Oid dbid, uint64 queryid)
|
|||||||
key.queryid = queryid;
|
key.queryid = queryid;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Remove the key if it exists, starting with the non-top-level entry.
|
* Reset the entry if it exists, starting with the non-top-level
|
||||||
|
* entry.
|
||||||
*/
|
*/
|
||||||
key.toplevel = false;
|
key.toplevel = false;
|
||||||
entry = (pgssEntry *) hash_search(pgss_hash, &key, HASH_REMOVE, NULL);
|
entry = (pgssEntry *) hash_search(pgss_hash, &key, HASH_FIND, NULL);
|
||||||
if (entry) /* found */
|
|
||||||
num_remove++;
|
|
||||||
|
|
||||||
/* Also remove the top-level entry if it exists. */
|
SINGLE_ENTRY_RESET(entry);
|
||||||
|
|
||||||
|
/* Also reset the top-level entry if it exists. */
|
||||||
key.toplevel = true;
|
key.toplevel = true;
|
||||||
entry = (pgssEntry *) hash_search(pgss_hash, &key, HASH_REMOVE, NULL);
|
entry = (pgssEntry *) hash_search(pgss_hash, &key, HASH_FIND, NULL);
|
||||||
if (entry) /* found */
|
|
||||||
num_remove++;
|
SINGLE_ENTRY_RESET(entry);
|
||||||
}
|
}
|
||||||
else if (userid != 0 || dbid != 0 || queryid != UINT64CONST(0))
|
else if (userid != 0 || dbid != 0 || queryid != UINT64CONST(0))
|
||||||
{
|
{
|
||||||
/* Remove entries corresponding to valid parameters. */
|
/* Reset entries corresponding to valid parameters. */
|
||||||
hash_seq_init(&hash_seq, pgss_hash);
|
hash_seq_init(&hash_seq, pgss_hash);
|
||||||
while ((entry = hash_seq_search(&hash_seq)) != NULL)
|
while ((entry = hash_seq_search(&hash_seq)) != NULL)
|
||||||
{
|
{
|
||||||
@ -2646,19 +2710,17 @@ entry_reset(Oid userid, Oid dbid, uint64 queryid)
|
|||||||
(!dbid || entry->key.dbid == dbid) &&
|
(!dbid || entry->key.dbid == dbid) &&
|
||||||
(!queryid || entry->key.queryid == queryid))
|
(!queryid || entry->key.queryid == queryid))
|
||||||
{
|
{
|
||||||
hash_search(pgss_hash, &entry->key, HASH_REMOVE, NULL);
|
SINGLE_ENTRY_RESET(entry);
|
||||||
num_remove++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Remove all entries. */
|
/* Reset all entries. */
|
||||||
hash_seq_init(&hash_seq, pgss_hash);
|
hash_seq_init(&hash_seq, pgss_hash);
|
||||||
while ((entry = hash_seq_search(&hash_seq)) != NULL)
|
while ((entry = hash_seq_search(&hash_seq)) != NULL)
|
||||||
{
|
{
|
||||||
hash_search(pgss_hash, &entry->key, HASH_REMOVE, NULL);
|
SINGLE_ENTRY_RESET(entry);
|
||||||
num_remove++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2672,7 +2734,6 @@ entry_reset(Oid userid, Oid dbid, uint64 queryid)
|
|||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
volatile pgssSharedState *s = (volatile pgssSharedState *) pgss;
|
volatile pgssSharedState *s = (volatile pgssSharedState *) pgss;
|
||||||
TimestampTz stats_reset = GetCurrentTimestamp();
|
|
||||||
|
|
||||||
SpinLockAcquire(&s->mutex);
|
SpinLockAcquire(&s->mutex);
|
||||||
s->stats.dealloc = 0;
|
s->stats.dealloc = 0;
|
||||||
@ -2710,6 +2771,8 @@ done:
|
|||||||
|
|
||||||
release_lock:
|
release_lock:
|
||||||
LWLockRelease(pgss->lock);
|
LWLockRelease(pgss->lock);
|
||||||
|
|
||||||
|
return stats_reset;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
114
contrib/pg_stat_statements/sql/entry_timestamp.sql
Normal file
114
contrib/pg_stat_statements/sql/entry_timestamp.sql
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
--
|
||||||
|
-- statement timestamps
|
||||||
|
--
|
||||||
|
|
||||||
|
-- planning time is needed during tests
|
||||||
|
SET pg_stat_statements.track_planning = TRUE;
|
||||||
|
|
||||||
|
SELECT 1 AS "STMTTS1";
|
||||||
|
SELECT now() AS ref_ts \gset
|
||||||
|
SELECT 1,2 AS "STMTTS2";
|
||||||
|
SELECT stats_since >= :'ref_ts', count(*) FROM pg_stat_statements
|
||||||
|
WHERE query LIKE '%STMTTS%'
|
||||||
|
GROUP BY stats_since >= :'ref_ts'
|
||||||
|
ORDER BY stats_since >= :'ref_ts';
|
||||||
|
|
||||||
|
SELECT now() AS ref_ts \gset
|
||||||
|
SELECT
|
||||||
|
count(*) as total,
|
||||||
|
count(*) FILTER (
|
||||||
|
WHERE min_plan_time + max_plan_time = 0
|
||||||
|
) as minmax_plan_zero,
|
||||||
|
count(*) FILTER (
|
||||||
|
WHERE min_exec_time + max_exec_time = 0
|
||||||
|
) as minmax_exec_zero,
|
||||||
|
count(*) FILTER (
|
||||||
|
WHERE minmax_stats_since >= :'ref_ts'
|
||||||
|
) as minmax_stats_since_after_ref,
|
||||||
|
count(*) FILTER (
|
||||||
|
WHERE stats_since >= :'ref_ts'
|
||||||
|
) as stats_since_after_ref
|
||||||
|
FROM pg_stat_statements
|
||||||
|
WHERE query LIKE '%STMTTS%';
|
||||||
|
|
||||||
|
-- Perform single min/max reset
|
||||||
|
SELECT pg_stat_statements_reset(0, 0, queryid, true) AS minmax_reset_ts
|
||||||
|
FROM pg_stat_statements
|
||||||
|
WHERE query LIKE '%STMTTS1%' \gset
|
||||||
|
|
||||||
|
-- check
|
||||||
|
SELECT
|
||||||
|
count(*) as total,
|
||||||
|
count(*) FILTER (
|
||||||
|
WHERE min_plan_time + max_plan_time = 0
|
||||||
|
) as minmax_plan_zero,
|
||||||
|
count(*) FILTER (
|
||||||
|
WHERE min_exec_time + max_exec_time = 0
|
||||||
|
) as minmax_exec_zero,
|
||||||
|
count(*) FILTER (
|
||||||
|
WHERE minmax_stats_since >= :'ref_ts'
|
||||||
|
) as minmax_stats_since_after_ref,
|
||||||
|
count(*) FILTER (
|
||||||
|
WHERE stats_since >= :'ref_ts'
|
||||||
|
) as stats_since_after_ref
|
||||||
|
FROM pg_stat_statements
|
||||||
|
WHERE query LIKE '%STMTTS%';
|
||||||
|
|
||||||
|
-- check minmax reset timestamps
|
||||||
|
SELECT
|
||||||
|
query, minmax_stats_since = :'minmax_reset_ts' AS reset_ts_match
|
||||||
|
FROM pg_stat_statements
|
||||||
|
WHERE query LIKE '%STMTTS%'
|
||||||
|
ORDER BY query COLLATE "C";
|
||||||
|
|
||||||
|
-- check that minmax reset does not set stats_reset
|
||||||
|
SELECT
|
||||||
|
stats_reset = :'minmax_reset_ts' AS stats_reset_ts_match
|
||||||
|
FROM pg_stat_statements_info;
|
||||||
|
|
||||||
|
-- Perform common min/max reset
|
||||||
|
SELECT pg_stat_statements_reset(0, 0, 0, true) AS minmax_reset_ts \gset
|
||||||
|
|
||||||
|
-- check again
|
||||||
|
SELECT
|
||||||
|
count(*) as total,
|
||||||
|
count(*) FILTER (
|
||||||
|
WHERE min_plan_time + max_plan_time = 0
|
||||||
|
) as minmax_plan_zero,
|
||||||
|
count(*) FILTER (
|
||||||
|
WHERE min_exec_time + max_exec_time = 0
|
||||||
|
) as minmax_exec_zero,
|
||||||
|
count(*) FILTER (
|
||||||
|
WHERE minmax_stats_since >= :'ref_ts'
|
||||||
|
) as minmax_ts_after_ref,
|
||||||
|
count(*) FILTER (
|
||||||
|
WHERE minmax_stats_since = :'minmax_reset_ts'
|
||||||
|
) as minmax_ts_match,
|
||||||
|
count(*) FILTER (
|
||||||
|
WHERE stats_since >= :'ref_ts'
|
||||||
|
) as stats_since_after_ref
|
||||||
|
FROM pg_stat_statements
|
||||||
|
WHERE query LIKE '%STMTTS%';
|
||||||
|
|
||||||
|
-- Execute first query once more to check stats update
|
||||||
|
SELECT 1 AS "STMTTS1";
|
||||||
|
|
||||||
|
-- check
|
||||||
|
-- we don't check planing times here to be independent of
|
||||||
|
-- plan caching approach
|
||||||
|
SELECT
|
||||||
|
count(*) as total,
|
||||||
|
count(*) FILTER (
|
||||||
|
WHERE min_exec_time + max_exec_time = 0
|
||||||
|
) as minmax_exec_zero,
|
||||||
|
count(*) FILTER (
|
||||||
|
WHERE minmax_stats_since >= :'ref_ts'
|
||||||
|
) as minmax_ts_after_ref,
|
||||||
|
count(*) FILTER (
|
||||||
|
WHERE stats_since >= :'ref_ts'
|
||||||
|
) as stats_since_after_ref
|
||||||
|
FROM pg_stat_statements
|
||||||
|
WHERE query LIKE '%STMTTS%';
|
||||||
|
|
||||||
|
-- Cleanup
|
||||||
|
SELECT pg_stat_statements_reset() IS NOT NULL AS t;
|
@ -48,9 +48,11 @@ AlTER EXTENSION pg_stat_statements UPDATE TO '1.10';
|
|||||||
\d pg_stat_statements
|
\d pg_stat_statements
|
||||||
SELECT count(*) > 0 AS has_data FROM pg_stat_statements;
|
SELECT count(*) > 0 AS has_data FROM pg_stat_statements;
|
||||||
|
|
||||||
-- New views for pg_stat_statements in 1.11
|
-- New functions and views for pg_stat_statements in 1.11
|
||||||
AlTER EXTENSION pg_stat_statements UPDATE TO '1.11';
|
AlTER EXTENSION pg_stat_statements UPDATE TO '1.11';
|
||||||
\d pg_stat_statements
|
\d pg_stat_statements
|
||||||
SELECT count(*) > 0 AS has_data FROM pg_stat_statements;
|
SELECT count(*) > 0 AS has_data FROM pg_stat_statements;
|
||||||
|
-- New parameter minmax_only of pg_stat_statements_reset function
|
||||||
|
SELECT pg_get_functiondef('pg_stat_statements_reset'::regproc);
|
||||||
|
|
||||||
DROP EXTENSION pg_stat_statements;
|
DROP EXTENSION pg_stat_statements;
|
||||||
|
@ -140,9 +140,12 @@
|
|||||||
<structfield>min_plan_time</structfield> <type>double precision</type>
|
<structfield>min_plan_time</structfield> <type>double precision</type>
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
Minimum time spent planning the statement, in milliseconds
|
Minimum time spent planning the statement, in milliseconds.
|
||||||
(if <varname>pg_stat_statements.track_planning</varname> is enabled,
|
This field will be zero if <varname>pg_stat_statements.track_planning</varname>
|
||||||
otherwise zero)
|
is disabled, or if the counter has been reset using the
|
||||||
|
<function>pg_stat_statements_reset</function> function with the
|
||||||
|
<structfield>minmax_only</structfield> parameter set to <literal>true</literal>
|
||||||
|
and never been planned since.
|
||||||
</para></entry>
|
</para></entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
@ -151,9 +154,12 @@
|
|||||||
<structfield>max_plan_time</structfield> <type>double precision</type>
|
<structfield>max_plan_time</structfield> <type>double precision</type>
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
Maximum time spent planning the statement, in milliseconds
|
Maximum time spent planning the statement, in milliseconds.
|
||||||
(if <varname>pg_stat_statements.track_planning</varname> is enabled,
|
This field will be zero if <varname>pg_stat_statements.track_planning</varname>
|
||||||
otherwise zero)
|
is disabled, or if the counter has been reset using the
|
||||||
|
<function>pg_stat_statements_reset</function> function with the
|
||||||
|
<structfield>minmax_only</structfield> parameter set to <literal>true</literal>
|
||||||
|
and never been planned since.
|
||||||
</para></entry>
|
</para></entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
@ -203,7 +209,11 @@
|
|||||||
<structfield>min_exec_time</structfield> <type>double precision</type>
|
<structfield>min_exec_time</structfield> <type>double precision</type>
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
Minimum time spent executing the statement, in milliseconds
|
Minimum time spent executing the statement, in milliseconds,
|
||||||
|
this field will be zero until this statement
|
||||||
|
is executed first time after reset performed by the
|
||||||
|
<function>pg_stat_statements_reset</function> function with the
|
||||||
|
<structfield>minmax_only</structfield> parameter set to <literal>true</literal>
|
||||||
</para></entry>
|
</para></entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
@ -212,7 +222,11 @@
|
|||||||
<structfield>max_exec_time</structfield> <type>double precision</type>
|
<structfield>max_exec_time</structfield> <type>double precision</type>
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
Maximum time spent executing the statement, in milliseconds
|
Maximum time spent executing the statement, in milliseconds,
|
||||||
|
this field will be zero until this statement
|
||||||
|
is executed first time after reset performed by the
|
||||||
|
<function>pg_stat_statements_reset</function> function with the
|
||||||
|
<structfield>minmax_only</structfield> parameter set to <literal>true</literal>
|
||||||
</para></entry>
|
</para></entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
@ -512,6 +526,28 @@
|
|||||||
functions, in milliseconds
|
functions, in milliseconds
|
||||||
</para></entry>
|
</para></entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
|
<row>
|
||||||
|
<entry role="catalog_table_entry"><para role="column_definition">
|
||||||
|
<structfield>stats_since</structfield> <type>timestamp with time zone</type>
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Time at which statistics gathering started for this statement
|
||||||
|
</para></entry>
|
||||||
|
</row>
|
||||||
|
|
||||||
|
<row>
|
||||||
|
<entry role="catalog_table_entry"><para role="column_definition">
|
||||||
|
<structfield>minmax_stats_since</structfield> <type>timestamp with time zone</type>
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Time at which min/max statistics gathering started for this
|
||||||
|
statement (fields <structfield>min_plan_time</structfield>,
|
||||||
|
<structfield>max_plan_time</structfield>,
|
||||||
|
<structfield>min_exec_time</structfield> and
|
||||||
|
<structfield>max_exec_time</structfield>)
|
||||||
|
</para></entry>
|
||||||
|
</row>
|
||||||
</tbody>
|
</tbody>
|
||||||
</tgroup>
|
</tgroup>
|
||||||
</table>
|
</table>
|
||||||
@ -713,7 +749,8 @@
|
|||||||
<variablelist>
|
<variablelist>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>
|
<term>
|
||||||
<function>pg_stat_statements_reset(userid Oid, dbid Oid, queryid bigint) returns void</function>
|
<function>pg_stat_statements_reset(userid Oid, dbid Oid, queryid
|
||||||
|
bigint, minmax_only boolean) returns timestamp with time zone</function>
|
||||||
<indexterm>
|
<indexterm>
|
||||||
<primary>pg_stat_statements_reset</primary>
|
<primary>pg_stat_statements_reset</primary>
|
||||||
</indexterm>
|
</indexterm>
|
||||||
@ -732,6 +769,20 @@
|
|||||||
If all statistics in the <filename>pg_stat_statements</filename>
|
If all statistics in the <filename>pg_stat_statements</filename>
|
||||||
view are discarded, it will also reset the statistics in the
|
view are discarded, it will also reset the statistics in the
|
||||||
<structname>pg_stat_statements_info</structname> view.
|
<structname>pg_stat_statements_info</structname> view.
|
||||||
|
When <structfield>minmax_only</structfield> is <literal>true</literal> only the
|
||||||
|
values of minimun and maximum planning and execution time will be reset (i.e.
|
||||||
|
<structfield>min_plan_time</structfield>, <structfield>max_plan_time</structfield>,
|
||||||
|
<structfield>min_exec_time</structfield> and <structfield>max_exec_time</structfield>
|
||||||
|
fields). The default value for <structfield>minmax_only</structfield> parameter is
|
||||||
|
<literal>false</literal>. Time of last min/max reset performed is shown in
|
||||||
|
<structfield>minmax_stats_since</structfield> field of the
|
||||||
|
<structname>pg_stat_statements</structname> view.
|
||||||
|
This function returns the time of a reset. This time is saved to
|
||||||
|
<structfield>stats_reset</structfield> field of
|
||||||
|
<structname>pg_stat_statements_info</structname> view or to
|
||||||
|
<structfield>minmax_stats_since</structfield> field of the
|
||||||
|
<structname>pg_stat_statements</structname> view if the corresponding reset was
|
||||||
|
actually performed.
|
||||||
By default, this function can only be executed by superusers.
|
By default, this function can only be executed by superusers.
|
||||||
Access may be granted to others using <command>GRANT</command>.
|
Access may be granted to others using <command>GRANT</command>.
|
||||||
</para>
|
</para>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user