mirror of
https://github.com/postgres/postgres.git
synced 2025-07-24 14:22:24 +03:00
Fix recovery_min_apply_delay test
Previously this test was relying too much on WAL replay to occur in the exact configured interval, which was unreliable on slow or overly busy servers. Use a custom loop instead of poll_query_until, which is hopefully more reliable. Per continued failures on buildfarm member hamster (which is probably the only one running this test suite) Author: Michaël Paquier
This commit is contained in:
@ -1,9 +1,10 @@
|
|||||||
# Checks for recovery_min_apply_delay
|
# Checks for recovery_min_apply_delay
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
|
|
||||||
use PostgresNode;
|
use PostgresNode;
|
||||||
use TestLib;
|
use TestLib;
|
||||||
use Test::More tests => 2;
|
use Test::More tests => 1;
|
||||||
|
|
||||||
# Initialize master node
|
# Initialize master node
|
||||||
my $node_master = get_new_node('master');
|
my $node_master = get_new_node('master');
|
||||||
@ -12,7 +13,7 @@ $node_master->start;
|
|||||||
|
|
||||||
# And some content
|
# And some content
|
||||||
$node_master->safe_psql('postgres',
|
$node_master->safe_psql('postgres',
|
||||||
"CREATE TABLE tab_int AS SELECT generate_series(1,10) AS a");
|
"CREATE TABLE tab_int AS SELECT generate_series(1, 10) AS a");
|
||||||
|
|
||||||
# Take backup
|
# Take backup
|
||||||
my $backup_name = 'my_backup';
|
my $backup_name = 'my_backup';
|
||||||
@ -20,30 +21,47 @@ $node_master->backup($backup_name);
|
|||||||
|
|
||||||
# Create streaming standby from backup
|
# Create streaming standby from backup
|
||||||
my $node_standby = get_new_node('standby');
|
my $node_standby = get_new_node('standby');
|
||||||
|
my $delay = 3;
|
||||||
$node_standby->init_from_backup($node_master, $backup_name,
|
$node_standby->init_from_backup($node_master, $backup_name,
|
||||||
has_streaming => 1);
|
has_streaming => 1);
|
||||||
$node_standby->append_conf(
|
$node_standby->append_conf(
|
||||||
'recovery.conf', qq(
|
'recovery.conf', qq(
|
||||||
recovery_min_apply_delay = '2s'
|
recovery_min_apply_delay = '${delay}s'
|
||||||
));
|
));
|
||||||
$node_standby->start;
|
$node_standby->start;
|
||||||
|
|
||||||
# Make new content on master and check its presence in standby
|
# Make new content on master and check its presence in standby depending
|
||||||
# depending on the delay of 2s applied above.
|
# on the delay applied above. Before doing the insertion, get the
|
||||||
|
# current timestamp that will be used as a comparison base. Even on slow
|
||||||
|
# machines, this allows to have a predictable behavior when comparing the
|
||||||
|
# delay between data insertion moment on master and replay time on standby.
|
||||||
|
my $master_insert_time = time();
|
||||||
$node_master->safe_psql('postgres',
|
$node_master->safe_psql('postgres',
|
||||||
"INSERT INTO tab_int VALUES (generate_series(11,20))");
|
"INSERT INTO tab_int VALUES (generate_series(11, 20))");
|
||||||
sleep 1;
|
|
||||||
|
|
||||||
# Here we should have only 10 rows
|
# Now wait for replay to complete on standby. We're done waiting when the
|
||||||
my $result = $node_standby->safe_psql('postgres', "SELECT count(*) FROM tab_int");
|
# slave has replayed up to the previously saved master LSN.
|
||||||
is($result, qq(10), 'check content with delay of 1s');
|
|
||||||
|
|
||||||
# Now wait for replay to complete on standby
|
|
||||||
my $until_lsn =
|
my $until_lsn =
|
||||||
$node_master->safe_psql('postgres', "SELECT pg_current_xlog_location();");
|
$node_master->safe_psql('postgres', "SELECT pg_current_xlog_location()");
|
||||||
my $caughtup_query =
|
|
||||||
"SELECT '$until_lsn'::pg_lsn <= pg_last_xlog_replay_location()";
|
my $remaining = 90;
|
||||||
$node_standby->poll_query_until('postgres', $caughtup_query)
|
while ($remaining-- > 0)
|
||||||
or die "Timed out while waiting for standby to catch up";
|
{
|
||||||
$result = $node_standby->safe_psql('postgres', "SELECT count(*) FROM tab_int");
|
# Done waiting?
|
||||||
is($result, qq(20), 'check content with delay of 2s');
|
my $replay_status =
|
||||||
|
$node_standby->safe_psql('postgres',
|
||||||
|
"SELECT (pg_last_xlog_replay_location() - '$until_lsn'::pg_lsn) >= 0");
|
||||||
|
last if $replay_status eq 't';
|
||||||
|
|
||||||
|
# No, sleep some more.
|
||||||
|
my $sleep = $master_insert_time + $delay - time();
|
||||||
|
$sleep = 1 if $sleep < 1;
|
||||||
|
sleep $sleep;
|
||||||
|
}
|
||||||
|
|
||||||
|
die "Maximum number of attempts reached ($remaining remain)" if $remaining < 0;
|
||||||
|
|
||||||
|
# This test is successful if and only if the LSN has been applied with at least
|
||||||
|
# the configured apply delay.
|
||||||
|
ok(time() - $master_insert_time >= $delay,
|
||||||
|
"Check that standby applies WAL only after replication delay");
|
||||||
|
Reference in New Issue
Block a user