diff --git a/contrib/pg_stat_statements/Makefile b/contrib/pg_stat_statements/Makefile index aecd1d6a2a0..7ee16e83509 100644 --- a/contrib/pg_stat_statements/Makefile +++ b/contrib/pg_stat_statements/Makefile @@ -19,7 +19,7 @@ LDFLAGS_SL += $(filter -lm, $(LIBS)) REGRESS_OPTS = --temp-config $(top_srcdir)/contrib/pg_stat_statements/pg_stat_statements.conf REGRESS = select dml cursors utility level_tracking planning \ - user_activity wal entry_timestamp cleanup oldextversions + user_activity wal entry_timestamp max cleanup oldextversions # Disabled because these tests require "shared_preload_libraries=pg_stat_statements", # which typical installcheck users do not have (e.g. buildfarm clients). NO_INSTALLCHECK = 1 diff --git a/contrib/pg_stat_statements/expected/max.out b/contrib/pg_stat_statements/expected/max.out new file mode 100644 index 00000000000..15e25316646 --- /dev/null +++ b/contrib/pg_stat_statements/expected/max.out @@ -0,0 +1,82 @@ +-- +-- Test deallocation of entries +-- +SHOW pg_stat_statements.max; + pg_stat_statements.max +------------------------ + 100 +(1 row) + +SET pg_stat_statements.track = 'all'; +-- Create 101 tables. +DO $$ +BEGIN + FOR i IN 1..101 LOOP + EXECUTE format('create table t%s (a int)', lpad(i::text, 3, '0')); + END LOOP; +END +$$; +SELECT pg_stat_statements_reset() IS NOT NULL AS t; + t +--- + t +(1 row) + +-- Run 98 queries. +DO $$ +BEGIN + FOR i IN 1..98 LOOP + EXECUTE format('select * from t%s', lpad(i::text, 3, '0')); + END LOOP; +END +$$; +-- All 98 queries should be registered. We just check the first and +-- last to keep the output small. +SELECT query FROM pg_stat_statements WHERE query LIKE '%t001%' OR query LIKE '%t098%' ORDER BY query; + query +-------------------- + select * from t001 + select * from t098 +(2 rows) + +-- Query tables 2 through 98 again, so they have a higher calls count. +-- Table 1 still has previous calls count. +DO $$ +BEGIN + FOR i IN 2..98 LOOP + EXECUTE format('select * from t%s', lpad(i::text, 3, '0')); + END LOOP; +END +$$; +-- Run 3 more queries. This will exceed the max and will cause the +-- least used query to be deallocated. (The queries for +-- pg_stat_statements themselves will also register, so fewer than 3 +-- queries will also cause overflow, but let's keep this scenario +-- self-contained.) +DO $$ +BEGIN + FOR i IN 99..101 LOOP + EXECUTE format('select * from t%s', lpad(i::text, 3, '0')); + END LOOP; +END +$$; +-- Check that the limit was kept. +SELECT count(*) <= 100 FROM pg_stat_statements; + ?column? +---------- + t +(1 row) + +-- Check that record for t001 has been deallocated. +SELECT query FROM pg_stat_statements WHERE query LIKE '%t001%' ORDER BY query; + query +------- +(0 rows) + +-- Check deallocation count. +SELECT dealloc > 0 AS t FROM pg_stat_statements_info; + t +--- + t +(1 row) + diff --git a/contrib/pg_stat_statements/meson.build b/contrib/pg_stat_statements/meson.build index 81fe1eb917d..a66acaa5b88 100644 --- a/contrib/pg_stat_statements/meson.build +++ b/contrib/pg_stat_statements/meson.build @@ -50,6 +50,7 @@ tests += { 'user_activity', 'wal', 'entry_timestamp', + 'max', 'cleanup', 'oldextversions', ], diff --git a/contrib/pg_stat_statements/pg_stat_statements.conf b/contrib/pg_stat_statements/pg_stat_statements.conf index 0e900d7119b..0119f681d7d 100644 --- a/contrib/pg_stat_statements/pg_stat_statements.conf +++ b/contrib/pg_stat_statements/pg_stat_statements.conf @@ -1,2 +1,4 @@ shared_preload_libraries = 'pg_stat_statements' max_prepared_transactions = 5 + +pg_stat_statements.max = 100 diff --git a/contrib/pg_stat_statements/sql/max.sql b/contrib/pg_stat_statements/sql/max.sql new file mode 100644 index 00000000000..155eec789a3 --- /dev/null +++ b/contrib/pg_stat_statements/sql/max.sql @@ -0,0 +1,61 @@ +-- +-- Test deallocation of entries +-- + +SHOW pg_stat_statements.max; + +SET pg_stat_statements.track = 'all'; + +-- Create 101 tables. +DO $$ +BEGIN + FOR i IN 1..101 LOOP + EXECUTE format('create table t%s (a int)', lpad(i::text, 3, '0')); + END LOOP; +END +$$; + +SELECT pg_stat_statements_reset() IS NOT NULL AS t; + +-- Run 98 queries. +DO $$ +BEGIN + FOR i IN 1..98 LOOP + EXECUTE format('select * from t%s', lpad(i::text, 3, '0')); + END LOOP; +END +$$; + +-- All 98 queries should be registered. We just check the first and +-- last to keep the output small. +SELECT query FROM pg_stat_statements WHERE query LIKE '%t001%' OR query LIKE '%t098%' ORDER BY query; + +-- Query tables 2 through 98 again, so they have a higher calls count. +-- Table 1 still has previous calls count. +DO $$ +BEGIN + FOR i IN 2..98 LOOP + EXECUTE format('select * from t%s', lpad(i::text, 3, '0')); + END LOOP; +END +$$; + +-- Run 3 more queries. This will exceed the max and will cause the +-- least used query to be deallocated. (The queries for +-- pg_stat_statements themselves will also register, so fewer than 3 +-- queries will also cause overflow, but let's keep this scenario +-- self-contained.) +DO $$ +BEGIN + FOR i IN 99..101 LOOP + EXECUTE format('select * from t%s', lpad(i::text, 3, '0')); + END LOOP; +END +$$; + +-- Check that the limit was kept. +SELECT count(*) <= 100 FROM pg_stat_statements; +-- Check that record for t001 has been deallocated. +SELECT query FROM pg_stat_statements WHERE query LIKE '%t001%' ORDER BY query; +-- Check deallocation count. +SELECT dealloc > 0 AS t FROM pg_stat_statements_info;