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.
8 use File
::Path
qw(rmtree);
9 use PostgreSQL
::Test
::Cluster
;
10 use PostgreSQL
::Test
::Utils
;
11 use Test
::More tests
=> 2;
14 my $node = PostgreSQL
::Test
::Cluster
->new('test');
15 $node->init(allows_streaming
=> 'logical');
16 $node->append_conf('postgresql.conf', 'synchronous_commit = on');
19 # Check that replication slot stats are expected.
22 local $Test::Builder
::Level
= $Test::Builder
::Level
+ 1;
24 my ($node, $expected, $msg) = @_;
26 my $result = $node->safe_psql(
28 SELECT slot_name
, total_txns
> 0 AS total_txn
,
29 total_bytes
> 0 AS total_bytes
30 FROM pg_stat_replication_slots
32 is
($result, $expected, $msg);
36 $node->safe_psql('postgres', "CREATE TABLE test_repl_stat(col1 int)");
38 # Create replication slots.
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');
48 $node->safe_psql('postgres',
49 "INSERT INTO test_repl_stat values(generate_series(1, 5));");
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');
63 # Wait for the statistics to be updated.
64 $node->poll_query_until(
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
73 $node->safe_psql('postgres',
74 "SELECT pg_drop_replication_slot('regression_slot4')");
79 # Verify statistics data present in pg_stat_replication_slots are sane after
83 qq(regression_slot1
|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.
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');
104 # Verify statistics data present in pg_stat_replication_slots are sane after
108 qq(regression_slot1
|t
|t
109 regression_slot2
|t
|t
),
110 'check replication statistics after removing the slot file');
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')");