diff --git a/contrib/pg_stat_statements/pg_stat_statements--1.8--1.9.sql b/contrib/pg_stat_statements/pg_stat_statements--1.8--1.9.sql index 2019a4ffe0..3504ca7eb1 100644 --- a/contrib/pg_stat_statements/pg_stat_statements--1.8--1.9.sql +++ b/contrib/pg_stat_statements/pg_stat_statements--1.8--1.9.sql @@ -5,9 +5,10 @@ --- Define pg_stat_statements_info CREATE FUNCTION pg_stat_statements_info( - OUT dealloc bigint + OUT dealloc bigint, + OUT stats_reset timestamp with time zone ) -RETURNS bigint +RETURNS record AS 'MODULE_PATHNAME' LANGUAGE C STRICT VOLATILE PARALLEL SAFE; diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c index 70cfdb2c9d..844f4ea808 100644 --- a/contrib/pg_stat_statements/pg_stat_statements.c +++ b/contrib/pg_stat_statements/pg_stat_statements.c @@ -81,6 +81,7 @@ #include "utils/acl.h" #include "utils/builtins.h" #include "utils/memutils.h" +#include "utils/timestamp.h" PG_MODULE_MAGIC; @@ -98,7 +99,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 = 0x20201126; +static const uint32 PGSS_FILE_HEADER = 0x20201214; /* PostgreSQL major version number, changes in which invalidate all entries */ static const uint32 PGSS_PG_MAJOR_VERSION = PG_VERSION_NUM / 100; @@ -199,6 +200,7 @@ typedef struct Counters typedef struct pgssGlobalStats { int64 dealloc; /* # of times entries were deallocated */ + TimestampTz stats_reset; /* timestamp with all stats reset */ } pgssGlobalStats; /* @@ -565,6 +567,7 @@ pgss_shmem_startup(void) pgss->n_writers = 0; pgss->gc_count = 0; pgss->stats.dealloc = 0; + pgss->stats.stats_reset = GetCurrentTimestamp(); } memset(&info, 0, sizeof(info)); @@ -1882,6 +1885,9 @@ pg_stat_statements_internal(FunctionCallInfo fcinfo, tuplestore_donestoring(tupstore); } +/* Number of output arguments (columns) for pg_stat_statements_info */ +#define PG_STAT_STATEMENTS_INFO_COLS 2 + /* * Return statistics of pg_stat_statements. */ @@ -1889,6 +1895,16 @@ Datum pg_stat_statements_info(PG_FUNCTION_ARGS) { pgssGlobalStats stats; + TupleDesc tupdesc; + Datum values[PG_STAT_STATEMENTS_INFO_COLS]; + bool nulls[PG_STAT_STATEMENTS_INFO_COLS]; + + /* Build a tuple descriptor for our result type */ + if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) + elog(ERROR, "return type must be a row type"); + + MemSet(values, 0, sizeof(values)); + MemSet(nulls, 0, sizeof(nulls)); /* Read global statistics for pg_stat_statements */ { @@ -1899,7 +1915,10 @@ pg_stat_statements_info(PG_FUNCTION_ARGS) SpinLockRelease(&s->mutex); } - PG_RETURN_INT64(stats.dealloc); + values[0] = Int64GetDatum(stats.dealloc); + values[1] = TimestampTzGetDatum(stats.stats_reset); + + PG_RETURN_DATUM(HeapTupleGetDatum(heap_form_tuple(tupdesc, values, nulls))); } /* @@ -2552,21 +2571,26 @@ entry_reset(Oid userid, Oid dbid, uint64 queryid) hash_search(pgss_hash, &entry->key, HASH_REMOVE, NULL); num_remove++; } - - /* Reset global statistics for pg_stat_statements */ - { - volatile pgssSharedState *s = (volatile pgssSharedState *) pgss; - - SpinLockAcquire(&s->mutex); - s->stats.dealloc = 0; - SpinLockRelease(&s->mutex); - } } /* All entries are removed? */ if (num_entries != num_remove) goto release_lock; + /* + * Reset global statistics for pg_stat_statements since all entries are + * removed. + */ + { + volatile pgssSharedState *s = (volatile pgssSharedState *) pgss; + TimestampTz stats_reset = GetCurrentTimestamp(); + + SpinLockAcquire(&s->mutex); + s->stats.dealloc = 0; + s->stats.stats_reset = stats_reset; + SpinLockRelease(&s->mutex); + } + /* * Write new empty query file, perhaps even creating a new one to recover * if the file was missing. diff --git a/doc/src/sgml/pgstatstatements.sgml b/doc/src/sgml/pgstatstatements.sgml index 81915ea69b..126ee31d9f 100644 --- a/doc/src/sgml/pgstatstatements.sgml +++ b/doc/src/sgml/pgstatstatements.sgml @@ -523,6 +523,16 @@ pg_stat_statements.max were observed + + + stats_reset timestamp with time zone + + + Time at which all statistics in the + pg_stat_statements view were last reset. + + + @@ -549,9 +559,11 @@ specified, the default value 0(invalid) is used for each of them and the statistics that match with other parameters will be reset. If no parameter is specified or all the specified parameters are - 0(invalid), it will discard all statistics including - the statistics that pg_stat_statements_info - displays. By default, this function can only be executed by superusers. + 0(invalid), it will discard all statistics. + If all statistics in the pg_stat_statements + view are discarded, it will also reset the statistics in the + pg_stat_statements_info view. + By default, this function can only be executed by superusers. Access may be granted to others using GRANT.