From f3de6afb3115e15ed69b9e06516abf3dcc856aa1 Mon Sep 17 00:00:00 2001 From: Andres Freund Date: Sun, 3 Apr 2022 15:17:16 -0700 Subject: [PATCH v68 22/31] pgstat: test: resetting of stats. --- src/test/recovery/t/006_logical_decoding.pl | 63 ++++++ src/test/regress/expected/stats.out | 212 ++++++++++++++++++++ src/test/regress/sql/stats.sql | 110 ++++++++++ 3 files changed, 385 insertions(+) diff --git a/src/test/recovery/t/006_logical_decoding.pl b/src/test/recovery/t/006_logical_decoding.pl index 9cec2792fc2..3ccced2ea24 100644 --- a/src/test/recovery/t/006_logical_decoding.pl +++ b/src/test/recovery/t/006_logical_decoding.pl @@ -200,6 +200,69 @@ chomp($logical_restart_lsn_post); ok(($logical_restart_lsn_pre cmp $logical_restart_lsn_post) == 0, "logical slot advance persists across restarts"); +my $stats_test_slot1 = 'test_slot'; +my $stats_test_slot2 = 'logical_slot'; + +# Test that reset works for pg_stat_replication_slots + +# Stats exist for stats test slot 1 +is($node_primary->safe_psql( + 'postgres', + qq(SELECT total_bytes > 0, stats_reset IS NULL FROM pg_stat_replication_slots WHERE slot_name = '$stats_test_slot1') +), qq(t|t), qq(Total bytes is > 0 and stats_reset is NULL for slot '$stats_test_slot1'.)); + +# Do reset of stats for stats test slot 1 +$node_primary->safe_psql( + 'postgres', + qq(SELECT pg_stat_reset_replication_slot('$stats_test_slot1')) +); + +# Get reset value after reset +my $reset1 = $node_primary->safe_psql( + 'postgres', + qq(SELECT stats_reset FROM pg_stat_replication_slots WHERE slot_name = '$stats_test_slot1') +); + +# Do reset again +$node_primary->safe_psql( + 'postgres', + qq(SELECT pg_stat_reset_replication_slot('$stats_test_slot1')) +); + +is($node_primary->safe_psql( + 'postgres', + qq(SELECT stats_reset > '$reset1'::timestamptz, total_bytes = 0 FROM pg_stat_replication_slots WHERE slot_name = '$stats_test_slot1') +), qq(t|t), qq(Check that reset timestamp is later after the second reset of stats for slot '$stats_test_slot1' and confirm total_bytes was set to 0.)); + +# Check that test slot 2 has NULL in reset timestamp +is($node_primary->safe_psql( + 'postgres', + qq(SELECT stats_reset IS NULL FROM pg_stat_replication_slots WHERE slot_name = '$stats_test_slot2') +), qq(t), qq(Stats_reset is NULL for slot '$stats_test_slot2' before reset.)); + +# Get reset value again for test slot 1 +$reset1 = $node_primary->safe_psql( + 'postgres', + qq(SELECT stats_reset FROM pg_stat_replication_slots WHERE slot_name = '$stats_test_slot1') +); + +# Reset stats for all replication slots +$node_primary->safe_psql( + 'postgres', + qq(SELECT pg_stat_reset_replication_slot(NULL)) +); + +# Check that test slot 2 reset timestamp is no longer NULL after reset +is($node_primary->safe_psql( + 'postgres', + qq(SELECT stats_reset IS NOT NULL FROM pg_stat_replication_slots WHERE slot_name = '$stats_test_slot2') +), qq(t), qq(Stats_reset is not NULL for slot '$stats_test_slot2' after reset all.)); + +is($node_primary->safe_psql( + 'postgres', + qq(SELECT stats_reset > '$reset1'::timestamptz FROM pg_stat_replication_slots WHERE slot_name = '$stats_test_slot1') +), qq(t), qq(Check that reset timestamp is later after resetting stats for slot '$stats_test_slot1' again.)); + # done with the node $node_primary->stop; diff --git a/src/test/regress/expected/stats.out b/src/test/regress/expected/stats.out index 890b5d7e5bc..24550d87a03 100644 --- a/src/test/regress/expected/stats.out +++ b/src/test/regress/expected/stats.out @@ -529,4 +529,216 @@ SELECT pg_stat_get_subscription_stats(NULL); (1 row) +----- +-- Test that various stats views are being properly populated +----- +-- Test that sessions is incremented when a new session is started in pg_stat_database +SELECT sessions AS db_stat_sessions FROM pg_stat_database WHERE datname = (SELECT current_database()) \gset +\c +SELECT sessions > :db_stat_sessions FROM pg_stat_database WHERE datname = (SELECT current_database()); + ?column? +---------- + t +(1 row) + +-- Test pg_stat_bgwriter checkpointer-related stat +SELECT checkpoints_req AS rqst_ckpts_before FROM pg_stat_bgwriter \gset +-- Test pg_stat_wal +SELECT wal_bytes AS wal_bytes_before FROM pg_stat_wal \gset +CREATE TABLE test_stats_temp(a int); +INSERT INTO test_stats_temp SELECT 1 FROM generate_series(1,1000)i; +-- Checkpoint twice: The checkpointer reports stats after reporting completion +-- of the checkpoint. But after a second checkpoint we'll see at least the +-- results of the first. +CHECKPOINT; +CHECKPOINT; +SELECT checkpoints_req > :rqst_ckpts_before FROM pg_stat_bgwriter; + ?column? +---------- + t +(1 row) + +SELECT wal_bytes > :wal_bytes_before FROM pg_stat_wal; + ?column? +---------- + t +(1 row) + +----- +-- Test that resetting stats works for reset timestamp +----- +SELECT stats_reset AS slru_commit_ts_reset_ts FROM pg_stat_slru WHERE name = 'CommitTs' \gset +SELECT stats_reset AS slru_notify_reset_ts FROM pg_stat_slru WHERE name = 'Notify' \gset +-- Test that reset_slru with a specified SLRU works. +SELECT pg_stat_reset_slru('CommitTs'); + pg_stat_reset_slru +-------------------- + +(1 row) + +SELECT pg_stat_force_next_flush(); + pg_stat_force_next_flush +-------------------------- + +(1 row) + +SELECT stats_reset > :'slru_commit_ts_reset_ts'::timestamptz FROM pg_stat_slru WHERE name = 'CommitTs'; + ?column? +---------- + t +(1 row) + +SELECT stats_reset AS slru_commit_ts_reset_ts FROM pg_stat_slru WHERE name = 'CommitTs' \gset +-- Test that multiple SLRUs are reset when no specific SLRU provided to reset function +SELECT pg_stat_reset_slru(NULL); + pg_stat_reset_slru +-------------------- + +(1 row) + +SELECT pg_stat_force_next_flush(); + pg_stat_force_next_flush +-------------------------- + +(1 row) + +SELECT stats_reset > :'slru_commit_ts_reset_ts'::timestamptz FROM pg_stat_slru WHERE name = 'CommitTs'; + ?column? +---------- + t +(1 row) + +SELECT stats_reset > :'slru_notify_reset_ts'::timestamptz FROM pg_stat_slru WHERE name = 'Notify'; + ?column? +---------- + t +(1 row) + +SELECT stats_reset AS archiver_reset_ts FROM pg_stat_archiver \gset +-- Test that reset_shared with archiver specified as the stats type works +SELECT pg_stat_reset_shared('archiver'); + pg_stat_reset_shared +---------------------- + +(1 row) + +SELECT pg_stat_force_next_flush(); + pg_stat_force_next_flush +-------------------------- + +(1 row) + +SELECT stats_reset > :'archiver_reset_ts'::timestamptz FROM pg_stat_archiver; + ?column? +---------- + t +(1 row) + +SELECT stats_reset AS archiver_reset_ts FROM pg_stat_archiver \gset +SELECT stats_reset AS bgwriter_reset_ts FROM pg_stat_bgwriter \gset +-- Test that reset_shared with bgwriter specified as the stats type works +SELECT pg_stat_reset_shared('bgwriter'); + pg_stat_reset_shared +---------------------- + +(1 row) + +SELECT pg_stat_force_next_flush(); + pg_stat_force_next_flush +-------------------------- + +(1 row) + +SELECT stats_reset > :'bgwriter_reset_ts'::timestamptz FROM pg_stat_bgwriter; + ?column? +---------- + t +(1 row) + +SELECT stats_reset AS bgwriter_reset_ts FROM pg_stat_bgwriter \gset +SELECT stats_reset AS wal_reset_ts FROM pg_stat_wal \gset +-- Test that reset_shared with wal specified as the stats type works +SELECT pg_stat_reset_shared('wal'); + pg_stat_reset_shared +---------------------- + +(1 row) + +SELECT pg_stat_force_next_flush(); + pg_stat_force_next_flush +-------------------------- + +(1 row) + +SELECT stats_reset > :'wal_reset_ts'::timestamptz FROM pg_stat_wal; + ?column? +---------- + t +(1 row) + +SELECT stats_reset AS wal_reset_ts FROM pg_stat_wal \gset +-- Test that reset_shared with no specified stats type resets all of them +SELECT pg_stat_reset_shared(NULL); + pg_stat_reset_shared +---------------------- + +(1 row) + +SELECT pg_stat_force_next_flush(); + pg_stat_force_next_flush +-------------------------- + +(1 row) + +SELECT stats_reset > :'archiver_reset_ts'::timestamptz FROM pg_stat_archiver; + ?column? +---------- + f +(1 row) + +SELECT stats_reset > :'bgwriter_reset_ts'::timestamptz FROM pg_stat_bgwriter; + ?column? +---------- + f +(1 row) + +SELECT stats_reset > :'wal_reset_ts'::timestamptz FROM pg_stat_wal; + ?column? +---------- + f +(1 row) + +-- Test that reset works for pg_stat_database +-- Since pg_stat_database stats_reset starts out as NULL, reset it once first so we have something to compare it to +SELECT pg_stat_reset(); + pg_stat_reset +--------------- + +(1 row) + +SELECT pg_stat_force_next_flush(); + pg_stat_force_next_flush +-------------------------- + +(1 row) + +SELECT stats_reset AS db_reset_ts FROM pg_stat_database WHERE datname = (SELECT current_database()) \gset +SELECT pg_stat_reset(); + pg_stat_reset +--------------- + +(1 row) + +SELECT pg_stat_force_next_flush(); + pg_stat_force_next_flush +-------------------------- + +(1 row) + +SELECT stats_reset > :'db_reset_ts'::timestamptz FROM pg_stat_database WHERE datname = (SELECT current_database()); + ?column? +---------- + t +(1 row) + -- End of Stats Test diff --git a/src/test/regress/sql/stats.sql b/src/test/regress/sql/stats.sql index ae0d8e17c59..8b7282183d0 100644 --- a/src/test/regress/sql/stats.sql +++ b/src/test/regress/sql/stats.sql @@ -286,5 +286,115 @@ DROP TABLE prevstats; SELECT pg_stat_get_replication_slot(NULL); SELECT pg_stat_get_subscription_stats(NULL); +----- +-- Test that various stats views are being properly populated +----- + +-- Test that sessions is incremented when a new session is started in pg_stat_database +SELECT sessions AS db_stat_sessions FROM pg_stat_database WHERE datname = (SELECT current_database()) \gset +\c +SELECT sessions > :db_stat_sessions FROM pg_stat_database WHERE datname = (SELECT current_database()); + +-- Test pg_stat_bgwriter checkpointer-related stat + +SELECT checkpoints_req AS rqst_ckpts_before FROM pg_stat_bgwriter \gset + +-- Test pg_stat_wal + +SELECT wal_bytes AS wal_bytes_before FROM pg_stat_wal \gset + +CREATE TABLE test_stats_temp(a int); +INSERT INTO test_stats_temp SELECT 1 FROM generate_series(1,1000)i; + +-- Checkpoint twice: The checkpointer reports stats after reporting completion +-- of the checkpoint. But after a second checkpoint we'll see at least the +-- results of the first. +CHECKPOINT; +CHECKPOINT; + +SELECT checkpoints_req > :rqst_ckpts_before FROM pg_stat_bgwriter; +SELECT wal_bytes > :wal_bytes_before FROM pg_stat_wal; + +----- +-- Test that resetting stats works for reset timestamp +----- + +SELECT stats_reset AS slru_commit_ts_reset_ts FROM pg_stat_slru WHERE name = 'CommitTs' \gset + +SELECT stats_reset AS slru_notify_reset_ts FROM pg_stat_slru WHERE name = 'Notify' \gset + +-- Test that reset_slru with a specified SLRU works. +SELECT pg_stat_reset_slru('CommitTs'); + +SELECT pg_stat_force_next_flush(); + +SELECT stats_reset > :'slru_commit_ts_reset_ts'::timestamptz FROM pg_stat_slru WHERE name = 'CommitTs'; + +SELECT stats_reset AS slru_commit_ts_reset_ts FROM pg_stat_slru WHERE name = 'CommitTs' \gset + +-- Test that multiple SLRUs are reset when no specific SLRU provided to reset function +SELECT pg_stat_reset_slru(NULL); + +SELECT pg_stat_force_next_flush(); + +SELECT stats_reset > :'slru_commit_ts_reset_ts'::timestamptz FROM pg_stat_slru WHERE name = 'CommitTs'; +SELECT stats_reset > :'slru_notify_reset_ts'::timestamptz FROM pg_stat_slru WHERE name = 'Notify'; + +SELECT stats_reset AS archiver_reset_ts FROM pg_stat_archiver \gset + +-- Test that reset_shared with archiver specified as the stats type works +SELECT pg_stat_reset_shared('archiver'); + +SELECT pg_stat_force_next_flush(); + +SELECT stats_reset > :'archiver_reset_ts'::timestamptz FROM pg_stat_archiver; + +SELECT stats_reset AS archiver_reset_ts FROM pg_stat_archiver \gset + +SELECT stats_reset AS bgwriter_reset_ts FROM pg_stat_bgwriter \gset + +-- Test that reset_shared with bgwriter specified as the stats type works +SELECT pg_stat_reset_shared('bgwriter'); + +SELECT pg_stat_force_next_flush(); + +SELECT stats_reset > :'bgwriter_reset_ts'::timestamptz FROM pg_stat_bgwriter; + +SELECT stats_reset AS bgwriter_reset_ts FROM pg_stat_bgwriter \gset + +SELECT stats_reset AS wal_reset_ts FROM pg_stat_wal \gset + +-- Test that reset_shared with wal specified as the stats type works +SELECT pg_stat_reset_shared('wal'); + +SELECT pg_stat_force_next_flush(); + +SELECT stats_reset > :'wal_reset_ts'::timestamptz FROM pg_stat_wal; + +SELECT stats_reset AS wal_reset_ts FROM pg_stat_wal \gset + +-- Test that reset_shared with no specified stats type resets all of them +SELECT pg_stat_reset_shared(NULL); + +SELECT pg_stat_force_next_flush(); + +SELECT stats_reset > :'archiver_reset_ts'::timestamptz FROM pg_stat_archiver; +SELECT stats_reset > :'bgwriter_reset_ts'::timestamptz FROM pg_stat_bgwriter; +SELECT stats_reset > :'wal_reset_ts'::timestamptz FROM pg_stat_wal; + +-- Test that reset works for pg_stat_database + +-- Since pg_stat_database stats_reset starts out as NULL, reset it once first so we have something to compare it to +SELECT pg_stat_reset(); + +SELECT pg_stat_force_next_flush(); + +SELECT stats_reset AS db_reset_ts FROM pg_stat_database WHERE datname = (SELECT current_database()) \gset + +SELECT pg_stat_reset(); + +SELECT pg_stat_force_next_flush(); + +SELECT stats_reset > :'db_reset_ts'::timestamptz FROM pg_stat_database WHERE datname = (SELECT current_database()); -- End of Stats Test -- 2.35.1.677.gabf474a5dd