From 966ee151cab2cd35bf9f70ab799311010c6a3305 Mon Sep 17 00:00:00 2001 From: Lukas Fittl Date: Sat, 28 Feb 2026 14:56:28 -0800 Subject: [PATCH v1] pg_stat_statements: Add gc_count and query_file_size to pgss_info This surfaces two internal metrics to end-users and monitoring scripts that allow using pg_stat_statements more effectively: The "gc_count" field complements the existing deallocation counter ("dealloc"), but counts up when the actual query text garbage collection occurrs, which is when the pg_stat_statements LWLock is typically held the longest, and significant I/O can occur for large query text files. The "query_file_size" field returns the current size of the query text file, as tracked by pg_stat_statements already, without requiring a stat() call. This can be useful for automated collection of query texts, to tweak how often to collect them, based on the query file size. It also helps correlate the amount of I/O performed with the actual file size, which can be up to 2x of the sum of the query texts actually returned. Bump pg_stat_statements version to 1.14 due to the addition of the two new columns to pg_stat_statements_info. Author: Lukas Fittl Reviewed by: Discussion: --- contrib/pg_stat_statements/Makefile | 1 + .../expected/oldextversions.out | 13 +++++++++ contrib/pg_stat_statements/meson.build | 1 + .../pg_stat_statements--1.13--1.14.sql | 28 +++++++++++++++++++ .../pg_stat_statements/pg_stat_statements.c | 10 +++++-- .../pg_stat_statements.control | 2 +- .../pg_stat_statements/sql/oldextversions.sql | 4 +++ doc/src/sgml/pgstatstatements.sgml | 20 +++++++++++++ 8 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 contrib/pg_stat_statements/pg_stat_statements--1.13--1.14.sql diff --git a/contrib/pg_stat_statements/Makefile b/contrib/pg_stat_statements/Makefile index c27e9529bb6..d7142f71cf7 100644 --- a/contrib/pg_stat_statements/Makefile +++ b/contrib/pg_stat_statements/Makefile @@ -7,6 +7,7 @@ OBJS = \ EXTENSION = pg_stat_statements DATA = pg_stat_statements--1.4.sql \ + pg_stat_statements--1.13--1.14.sql \ pg_stat_statements--1.12--1.13.sql \ pg_stat_statements--1.11--1.12.sql pg_stat_statements--1.10--1.11.sql \ pg_stat_statements--1.9--1.10.sql pg_stat_statements--1.8--1.9.sql \ diff --git a/contrib/pg_stat_statements/expected/oldextversions.out b/contrib/pg_stat_statements/expected/oldextversions.out index 726383a99d7..b9c7df4570a 100644 --- a/contrib/pg_stat_statements/expected/oldextversions.out +++ b/contrib/pg_stat_statements/expected/oldextversions.out @@ -474,4 +474,17 @@ SELECT count(*) > 0 AS has_data FROM pg_stat_statements; t (1 row) +-- New functions and views for pg_stat_statements_info in 1.14 +AlTER EXTENSION pg_stat_statements UPDATE TO '1.14'; +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 gc_count bigint, OUT query_file_size 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) + DROP EXTENSION pg_stat_statements; diff --git a/contrib/pg_stat_statements/meson.build b/contrib/pg_stat_statements/meson.build index 9d78cb88b7d..77148949c0d 100644 --- a/contrib/pg_stat_statements/meson.build +++ b/contrib/pg_stat_statements/meson.build @@ -21,6 +21,7 @@ contrib_targets += pg_stat_statements install_data( 'pg_stat_statements.control', 'pg_stat_statements--1.4.sql', + 'pg_stat_statements--1.13--1.14.sql', 'pg_stat_statements--1.12--1.13.sql', 'pg_stat_statements--1.11--1.12.sql', 'pg_stat_statements--1.10--1.11.sql', diff --git a/contrib/pg_stat_statements/pg_stat_statements--1.13--1.14.sql b/contrib/pg_stat_statements/pg_stat_statements--1.13--1.14.sql new file mode 100644 index 00000000000..6687ae4e1c3 --- /dev/null +++ b/contrib/pg_stat_statements/pg_stat_statements--1.13--1.14.sql @@ -0,0 +1,28 @@ +/* contrib/pg_stat_statements/pg_stat_statements--1.13--1.14.sql */ + +-- complain if script is sourced in psql, rather than via ALTER EXTENSION +\echo Use "ALTER EXTENSION pg_stat_statements UPDATE TO '1.14'" to load this file. \quit + +/* First we have to remove them from the extension */ +ALTER EXTENSION pg_stat_statements DROP VIEW pg_stat_statements_info; +ALTER EXTENSION pg_stat_statements DROP FUNCTION pg_stat_statements_info(); + +/* Then we can drop them */ +DROP VIEW pg_stat_statements_info; +DROP FUNCTION pg_stat_statements_info(); + +/* Now redefine */ +CREATE FUNCTION pg_stat_statements_info( + OUT dealloc bigint, + OUT gc_count bigint, + OUT query_file_size bigint, + OUT stats_reset timestamp with time zone +) +RETURNS record +AS 'MODULE_PATHNAME' +LANGUAGE C STRICT VOLATILE PARALLEL SAFE; + +CREATE VIEW pg_stat_statements_info AS + SELECT * FROM pg_stat_statements_info(); + +GRANT SELECT ON pg_stat_statements_info TO PUBLIC; diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c index 4a427533bd8..fcda847b4de 100644 --- a/contrib/pg_stat_statements/pg_stat_statements.c +++ b/contrib/pg_stat_statements/pg_stat_statements.c @@ -2049,7 +2049,7 @@ pg_stat_statements_internal(FunctionCallInfo fcinfo, } /* Number of output arguments (columns) for pg_stat_statements_info */ -#define PG_STAT_STATEMENTS_INFO_COLS 2 +#define PG_STAT_STATEMENTS_INFO_COLS 4 /* * Return statistics of pg_stat_statements. @@ -2061,6 +2061,8 @@ pg_stat_statements_info(PG_FUNCTION_ARGS) TupleDesc tupdesc; Datum values[PG_STAT_STATEMENTS_INFO_COLS] = {0}; bool nulls[PG_STAT_STATEMENTS_INFO_COLS] = {0}; + int64 gc_count, + extent; if (!pgss || !pgss_hash) ereport(ERROR, @@ -2074,10 +2076,14 @@ pg_stat_statements_info(PG_FUNCTION_ARGS) /* Read global statistics for pg_stat_statements */ SpinLockAcquire(&pgss->mutex); stats = pgss->stats; + gc_count = pgss->gc_count; + extent = pgss->extent; SpinLockRelease(&pgss->mutex); values[0] = Int64GetDatum(stats.dealloc); - values[1] = TimestampTzGetDatum(stats.stats_reset); + values[1] = Int64GetDatum(gc_count); + values[2] = Int64GetDatum(extent); + values[3] = TimestampTzGetDatum(stats.stats_reset); PG_RETURN_DATUM(HeapTupleGetDatum(heap_form_tuple(tupdesc, values, nulls))); } diff --git a/contrib/pg_stat_statements/pg_stat_statements.control b/contrib/pg_stat_statements/pg_stat_statements.control index 2eee0ceffa8..61ae41efc14 100644 --- a/contrib/pg_stat_statements/pg_stat_statements.control +++ b/contrib/pg_stat_statements/pg_stat_statements.control @@ -1,5 +1,5 @@ # pg_stat_statements extension comment = 'track planning and execution statistics of all SQL statements executed' -default_version = '1.13' +default_version = '1.14' module_pathname = '$libdir/pg_stat_statements' relocatable = true diff --git a/contrib/pg_stat_statements/sql/oldextversions.sql b/contrib/pg_stat_statements/sql/oldextversions.sql index e416efe9ffb..0f050173249 100644 --- a/contrib/pg_stat_statements/sql/oldextversions.sql +++ b/contrib/pg_stat_statements/sql/oldextversions.sql @@ -68,4 +68,8 @@ AlTER EXTENSION pg_stat_statements UPDATE TO '1.13'; \d pg_stat_statements SELECT count(*) > 0 AS has_data FROM pg_stat_statements; +-- New functions and views for pg_stat_statements_info in 1.14 +AlTER EXTENSION pg_stat_statements UPDATE TO '1.14'; +SELECT pg_get_functiondef('pg_stat_statements_info'::regproc); + DROP EXTENSION pg_stat_statements; diff --git a/doc/src/sgml/pgstatstatements.sgml b/doc/src/sgml/pgstatstatements.sgml index d753de5836e..11256ef9e3d 100644 --- a/doc/src/sgml/pgstatstatements.sgml +++ b/doc/src/sgml/pgstatstatements.sgml @@ -800,6 +800,26 @@ calls | 2 pg_stat_statements.max were observed + + + gc_count bigint + + + Total number of times the pg_stat_statements query text + file was rewritten for garbage collection (GC) purposes. This may occur after an + explicit call to pg_stat_statements_reset, or when sufficient + stale query texts have accumulated due to deallocations. + + + + + query_file_size bigint + + + The cumulative size (in bytes) of all query texts stored in the + pg_stat_statements query text file. + + stats_reset timestamp with time zone -- 2.47.1