2021-05-07 22:56:14 +08:00
|
|
|
|
2022-01-08 08:04:57 +08:00
|
|
|
# Copyright (c) 2021-2022, PostgreSQL Global Development Group
|
2021-05-07 22:56:14 +08:00
|
|
|
|
2021-04-16 10:04:43 +08:00
|
|
|
# Test replication statistics data in pg_stat_replication_slots is sane after
|
|
|
|
# drop replication slot and restart.
|
|
|
|
use strict;
|
|
|
|
use warnings;
|
2021-04-27 11:39:11 +08:00
|
|
|
use File::Path qw(rmtree);
|
2021-10-24 22:28:19 +08:00
|
|
|
use PostgreSQL::Test::Cluster;
|
|
|
|
use PostgreSQL::Test::Utils;
|
2022-02-12 03:54:44 +08:00
|
|
|
use Test::More;
|
2021-04-16 10:04:43 +08:00
|
|
|
|
|
|
|
# Test set-up
|
2021-10-24 22:28:19 +08:00
|
|
|
my $node = PostgreSQL::Test::Cluster->new('test');
|
2021-04-16 10:04:43 +08:00
|
|
|
$node->init(allows_streaming => 'logical');
|
|
|
|
$node->append_conf('postgresql.conf', 'synchronous_commit = on');
|
|
|
|
$node->start;
|
|
|
|
|
2021-04-27 11:39:11 +08:00
|
|
|
# Check that replication slot stats are expected.
|
|
|
|
sub test_slot_stats
|
|
|
|
{
|
2021-10-12 10:15:44 +08:00
|
|
|
local $Test::Builder::Level = $Test::Builder::Level + 1;
|
|
|
|
|
2021-04-27 11:39:11 +08:00
|
|
|
my ($node, $expected, $msg) = @_;
|
|
|
|
|
|
|
|
my $result = $node->safe_psql(
|
|
|
|
'postgres', qq[
|
|
|
|
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, $expected, $msg);
|
|
|
|
}
|
|
|
|
|
2021-04-16 10:04:43 +08:00
|
|
|
# Create table.
|
2021-04-27 11:39:11 +08:00
|
|
|
$node->safe_psql('postgres', "CREATE TABLE test_repl_stat(col1 int)");
|
2021-04-16 10:04:43 +08:00
|
|
|
|
|
|
|
# Create replication slots.
|
|
|
|
$node->safe_psql(
|
|
|
|
'postgres', qq[
|
|
|
|
SELECT pg_create_logical_replication_slot('regression_slot1', 'test_decoding');
|
|
|
|
SELECT pg_create_logical_replication_slot('regression_slot2', 'test_decoding');
|
|
|
|
SELECT pg_create_logical_replication_slot('regression_slot3', 'test_decoding');
|
|
|
|
SELECT pg_create_logical_replication_slot('regression_slot4', 'test_decoding');
|
|
|
|
]);
|
|
|
|
|
|
|
|
# Insert some data.
|
2021-04-27 11:39:11 +08:00
|
|
|
$node->safe_psql('postgres',
|
|
|
|
"INSERT INTO test_repl_stat values(generate_series(1, 5));");
|
2021-04-16 10:04:43 +08:00
|
|
|
|
|
|
|
$node->safe_psql(
|
|
|
|
'postgres', qq[
|
|
|
|
SELECT data FROM pg_logical_slot_get_changes('regression_slot1', NULL,
|
|
|
|
NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
|
|
|
SELECT data FROM pg_logical_slot_get_changes('regression_slot2', NULL,
|
|
|
|
NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
|
|
|
SELECT data FROM pg_logical_slot_get_changes('regression_slot3', NULL,
|
|
|
|
NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
|
|
|
SELECT data FROM pg_logical_slot_get_changes('regression_slot4', NULL,
|
|
|
|
NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
|
|
|
]);
|
|
|
|
|
|
|
|
# Wait for the statistics to be updated.
|
|
|
|
$node->poll_query_until(
|
|
|
|
'postgres', qq[
|
|
|
|
SELECT count(slot_name) >= 4 FROM pg_stat_replication_slots
|
|
|
|
WHERE slot_name ~ 'regression_slot'
|
|
|
|
AND total_txns > 0 AND total_bytes > 0;
|
|
|
|
]) or die "Timed out while waiting for statistics to be updated";
|
|
|
|
|
|
|
|
# Test to drop one of the replication slot and verify replication statistics data is
|
|
|
|
# fine after restart.
|
2021-04-27 11:39:11 +08:00
|
|
|
$node->safe_psql('postgres',
|
|
|
|
"SELECT pg_drop_replication_slot('regression_slot4')");
|
2021-04-16 10:04:43 +08:00
|
|
|
|
|
|
|
$node->stop;
|
|
|
|
$node->start;
|
|
|
|
|
|
|
|
# Verify statistics data present in pg_stat_replication_slots are sane after
|
|
|
|
# restart.
|
2021-04-27 11:39:11 +08:00
|
|
|
test_slot_stats(
|
|
|
|
$node,
|
|
|
|
qq(regression_slot1|t|t
|
2021-04-16 10:04:43 +08:00
|
|
|
regression_slot2|t|t
|
2021-04-27 11:39:11 +08:00
|
|
|
regression_slot3|t|t),
|
|
|
|
'check replication statistics are updated');
|
|
|
|
|
|
|
|
# Test to remove one of the replication slots and adjust
|
|
|
|
# max_replication_slots accordingly to the number of slots. This leads
|
|
|
|
# to a mismatch between the number of slots present in the stats file and the
|
2022-04-07 04:56:06 +08:00
|
|
|
# number of stats present in shared memory. We verify
|
2021-04-27 11:39:11 +08:00
|
|
|
# replication statistics data is fine after restart.
|
|
|
|
|
|
|
|
$node->stop;
|
|
|
|
my $datadir = $node->data_dir;
|
|
|
|
my $slot3_replslotdir = "$datadir/pg_replslot/regression_slot3";
|
|
|
|
|
|
|
|
rmtree($slot3_replslotdir);
|
|
|
|
|
|
|
|
$node->append_conf('postgresql.conf', 'max_replication_slots = 2');
|
|
|
|
$node->start;
|
|
|
|
|
|
|
|
# Verify statistics data present in pg_stat_replication_slots are sane after
|
|
|
|
# restart.
|
|
|
|
test_slot_stats(
|
|
|
|
$node,
|
|
|
|
qq(regression_slot1|t|t
|
|
|
|
regression_slot2|t|t),
|
|
|
|
'check replication statistics after removing the slot file');
|
2021-04-16 10:04:43 +08:00
|
|
|
|
|
|
|
# cleanup
|
|
|
|
$node->safe_psql('postgres', "DROP TABLE test_repl_stat");
|
2021-04-27 11:39:11 +08:00
|
|
|
$node->safe_psql('postgres',
|
|
|
|
"SELECT pg_drop_replication_slot('regression_slot1')");
|
|
|
|
$node->safe_psql('postgres',
|
|
|
|
"SELECT pg_drop_replication_slot('regression_slot2')");
|
2021-04-16 10:04:43 +08:00
|
|
|
|
|
|
|
# shutdown
|
|
|
|
$node->stop;
|
2022-02-12 03:54:44 +08:00
|
|
|
|
|
|
|
done_testing();
|