Update copyright for 2022
[pgsql.git] / contrib / test_decoding / t / 001_repl_stats.pl
blob36fb36e665f0fa3d2558d7c692d92e2bcf4bfe88
2 # Copyright (c) 2021-2022, PostgreSQL Global Development Group
4 # Test replication statistics data in pg_stat_replication_slots is sane after
5 # drop replication slot and restart.
6 use strict;
7 use warnings;
8 use File::Path qw(rmtree);
9 use PostgreSQL::Test::Cluster;
10 use PostgreSQL::Test::Utils;
11 use Test::More tests => 2;
13 # Test set-up
14 my $node = PostgreSQL::Test::Cluster->new('test');
15 $node->init(allows_streaming => 'logical');
16 $node->append_conf('postgresql.conf', 'synchronous_commit = on');
17 $node->start;
19 # Check that replication slot stats are expected.
20 sub test_slot_stats
22 local $Test::Builder::Level = $Test::Builder::Level + 1;
24 my ($node, $expected, $msg) = @_;
26 my $result = $node->safe_psql(
27 'postgres', qq[
28 SELECT slot_name, total_txns > 0 AS total_txn,
29 total_bytes > 0 AS total_bytes
30 FROM pg_stat_replication_slots
31 ORDER BY slot_name]);
32 is($result, $expected, $msg);
35 # Create table.
36 $node->safe_psql('postgres', "CREATE TABLE test_repl_stat(col1 int)");
38 # Create replication slots.
39 $node->safe_psql(
40 'postgres', qq[
41 SELECT pg_create_logical_replication_slot('regression_slot1', 'test_decoding');
42 SELECT pg_create_logical_replication_slot('regression_slot2', 'test_decoding');
43 SELECT pg_create_logical_replication_slot('regression_slot3', 'test_decoding');
44 SELECT pg_create_logical_replication_slot('regression_slot4', 'test_decoding');
45 ]);
47 # Insert some data.
48 $node->safe_psql('postgres',
49 "INSERT INTO test_repl_stat values(generate_series(1, 5));");
51 $node->safe_psql(
52 'postgres', qq[
53 SELECT data FROM pg_logical_slot_get_changes('regression_slot1', NULL,
54 NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
55 SELECT data FROM pg_logical_slot_get_changes('regression_slot2', NULL,
56 NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
57 SELECT data FROM pg_logical_slot_get_changes('regression_slot3', NULL,
58 NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
59 SELECT data FROM pg_logical_slot_get_changes('regression_slot4', NULL,
60 NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
61 ]);
63 # Wait for the statistics to be updated.
64 $node->poll_query_until(
65 'postgres', qq[
66 SELECT count(slot_name) >= 4 FROM pg_stat_replication_slots
67 WHERE slot_name ~ 'regression_slot'
68 AND total_txns > 0 AND total_bytes > 0;
69 ]) or die "Timed out while waiting for statistics to be updated";
71 # Test to drop one of the replication slot and verify replication statistics data is
72 # fine after restart.
73 $node->safe_psql('postgres',
74 "SELECT pg_drop_replication_slot('regression_slot4')");
76 $node->stop;
77 $node->start;
79 # Verify statistics data present in pg_stat_replication_slots are sane after
80 # restart.
81 test_slot_stats(
82 $node,
83 qq(regression_slot1|t|t
84 regression_slot2|t|t
85 regression_slot3|t|t),
86 'check replication statistics are updated');
88 # Test to remove one of the replication slots and adjust
89 # max_replication_slots accordingly to the number of slots. This leads
90 # to a mismatch between the number of slots present in the stats file and the
91 # number of stats present in the shared memory, simulating the scenario for
92 # drop slot message lost by the statistics collector process. We verify
93 # replication statistics data is fine after restart.
95 $node->stop;
96 my $datadir = $node->data_dir;
97 my $slot3_replslotdir = "$datadir/pg_replslot/regression_slot3";
99 rmtree($slot3_replslotdir);
101 $node->append_conf('postgresql.conf', 'max_replication_slots = 2');
102 $node->start;
104 # Verify statistics data present in pg_stat_replication_slots are sane after
105 # restart.
106 test_slot_stats(
107 $node,
108 qq(regression_slot1|t|t
109 regression_slot2|t|t),
110 'check replication statistics after removing the slot file');
112 # cleanup
113 $node->safe_psql('postgres', "DROP TABLE test_repl_stat");
114 $node->safe_psql('postgres',
115 "SELECT pg_drop_replication_slot('regression_slot1')");
116 $node->safe_psql('postgres',
117 "SELECT pg_drop_replication_slot('regression_slot2')");
119 # shutdown
120 $node->stop;