From d4be3220eaba71b8c6916a85314c43682bea9a33 Mon Sep 17 00:00:00 2001 From: vignesh Date: Mon, 5 Apr 2021 18:17:21 +0530 Subject: [PATCH v3 2/3] Added tests for verification of logical replication statistics. Added tests for verification of logical replication statistics after restart of server. --- contrib/test_decoding/Makefile | 2 + contrib/test_decoding/t/001_repl_stats.pl | 112 ++++++++++++++++++++++ 2 files changed, 114 insertions(+) create mode 100644 contrib/test_decoding/t/001_repl_stats.pl diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile index c5e28ce5cc..9a31e0b879 100644 --- a/contrib/test_decoding/Makefile +++ b/contrib/test_decoding/Makefile @@ -17,6 +17,8 @@ ISOLATION_OPTS = --temp-config $(top_srcdir)/contrib/test_decoding/logical.conf # typical installcheck users do not have (e.g. buildfarm clients). NO_INSTALLCHECK = 1 +TAP_TESTS = 1 + ifdef USE_PGXS PG_CONFIG = pg_config PGXS := $(shell $(PG_CONFIG) --pgxs) diff --git a/contrib/test_decoding/t/001_repl_stats.pl b/contrib/test_decoding/t/001_repl_stats.pl new file mode 100644 index 0000000000..4f50804bf4 --- /dev/null +++ b/contrib/test_decoding/t/001_repl_stats.pl @@ -0,0 +1,112 @@ +# Test replication statistics data in pg_stat_replication_slots is sane after +# drop replication slot and restart. +use strict; +use warnings; +use File::Path qw(rmtree); +use PostgresNode; +use TestLib; +use Test::More tests => 2; + +# Test set-up +my $node = get_new_node('test'); +$node->init(allows_streaming => 'logical'); +$node->append_conf('postgresql.conf', 'synchronous_commit = on'); +$node->start; + +$node->safe_psql('postgres', q(CREATE FUNCTION wait_for_decode_stats(check_reset bool, check_slot_name text) RETURNS void AS $$ +DECLARE + start_time timestamptz := clock_timestamp(); + txn_count bool; +BEGIN + -- we don't want to wait forever; loop will exit after 30 seconds + FOR i IN 1 .. 5 LOOP + + -- check to see if all updates have been reset/updated + SELECT (total_txns > 0) INTO txn_count + FROM pg_stat_replication_slots WHERE slot_name=check_slot_name; + + exit WHEN txn_count; + + -- wait a little + perform pg_sleep_for('100 milliseconds'); + + -- reset stats snapshot so we can test again + perform pg_stat_clear_snapshot(); + + END LOOP; + + -- report time waited in postmaster log (where it won't change test output) + RAISE LOG 'wait_for_decode_stats delayed % seconds', + extract(epoch from clock_timestamp() - start_time); +END +$$ LANGUAGE plpgsql; +)); + +# Create replication slots. +$node->safe_psql('postgres', + "SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot1', 'test_decoding')"); +$node->safe_psql('postgres', + "SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot2', 'test_decoding')"); +$node->safe_psql('postgres', + "SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot3', 'test_decoding')"); +$node->safe_psql('postgres', + "SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot4', 'test_decoding')"); + +# Create table. +$node->safe_psql('postgres', + "CREATE TABLE test_repl_stat(col1 int)"); +$node->safe_psql('postgres', + "SELECT data FROM pg_logical_slot_get_changes('regression_slot1', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1')"); +$node->safe_psql('postgres', + "SELECT data FROM pg_logical_slot_get_changes('regression_slot2', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1')"); +$node->safe_psql('postgres', + "SELECT data FROM pg_logical_slot_get_changes('regression_slot3', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1')"); +$node->safe_psql('postgres', + "SELECT data FROM pg_logical_slot_get_changes('regression_slot4', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1')"); + +# Insert some data. +$node->safe_psql('postgres', "INSERT INTO test_repl_stat values(generate_series(1, 5));"); + +# Wait for the statistics to be updated. +$node->safe_psql('postgres', "SELECT wait_for_decode_stats(true, 'regression_slot1')"); +$node->safe_psql('postgres', "SELECT wait_for_decode_stats(true, 'regression_slot2')"); +$node->safe_psql('postgres', "SELECT wait_for_decode_stats(true, 'regression_slot3')"); +$node->safe_psql('postgres', "SELECT wait_for_decode_stats(true, 'regression_slot4')"); + +# Test to verify replication statistics data is updated in +# pg_stat_replication_slots statistics view. +my $result = $node->safe_psql('postgres', + "SELECT slot_name, total_txns > 0 AS total_txn, total_bytes > 0 AS total_bytes + FROM pg_stat_replication_slots ORDER BY slot_name" +); +is($result, qq(regression_slot1|t|t +regression_slot2|t|t +regression_slot3|t|t +regression_slot4|t|t), 'check replication statistics are updated'); + +# Test to drop one of the subscribers and verify replication statistics data is +# fine after publisher is restarted. +$node->safe_psql('postgres', "SELECT pg_drop_replication_slot('regression_slot4')"); + +$node->stop; +$node->start; + +# Verify statistics data present in pg_stat_replication_slots are sane after +# publisher is restarted +$result = $node->safe_psql('postgres', + "SELECT slot_name, total_txns > 0 AS total_txn, total_bytes > 0 AS total_bytes + FROM pg_stat_replication_slots ORDER BY slot_name" +); +is($result, qq(regression_slot1|t|t +regression_slot2|t|t +regression_slot3|t|t), 'check replication statistics are updated'); + +# cleanup +$node->safe_psql('postgres', "DROP TABLE test_repl_stat"); +$node->safe_psql('postgres', "DROP FUNCTION wait_for_decode_stats"); +$node->safe_psql('postgres', "SELECT pg_drop_replication_slot('regression_slot1')"); +$node->safe_psql('postgres', "SELECT pg_drop_replication_slot('regression_slot2')"); +$node->safe_psql('postgres', "SELECT pg_drop_replication_slot('regression_slot3')"); + +# shutdown +$node->stop; -- 2.25.1