Skip to content

Commit 61608d3

Browse files
committed
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
1 parent f9aefcb commit 61608d3

File tree

1 file changed

+37
-19
lines changed

1 file changed

+37
-19
lines changed
+37-19
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
# Checks for recovery_min_apply_delay
22
use strict;
33
use warnings;
4+
45
use PostgresNode;
56
use TestLib;
6-
use Test::More tests => 2;
7+
use Test::More tests => 1;
78

89
# Initialize master node
910
my $node_master = get_new_node('master');
@@ -12,38 +13,55 @@
1213

1314
# And some content
1415
$node_master->safe_psql('postgres',
15-
"CREATE TABLE tab_int AS SELECT generate_series(1,10) AS a");
16+
"CREATE TABLE tab_int AS SELECT generate_series(1, 10) AS a");
1617

1718
# Take backup
1819
my $backup_name = 'my_backup';
1920
$node_master->backup($backup_name);
2021

2122
# Create streaming standby from backup
2223
my $node_standby = get_new_node('standby');
24+
my $delay = 3;
2325
$node_standby->init_from_backup($node_master, $backup_name,
2426
has_streaming => 1);
2527
$node_standby->append_conf(
2628
'recovery.conf', qq(
27-
recovery_min_apply_delay = '2s'
29+
recovery_min_apply_delay = '${delay}s'
2830
));
2931
$node_standby->start;
3032

31-
# Make new content on master and check its presence in standby
32-
# depending on the delay of 2s applied above.
33+
# Make new content on master and check its presence in standby depending
34+
# on the delay applied above. Before doing the insertion, get the
35+
# current timestamp that will be used as a comparison base. Even on slow
36+
# machines, this allows to have a predictable behavior when comparing the
37+
# delay between data insertion moment on master and replay time on standby.
38+
my $master_insert_time = time();
3339
$node_master->safe_psql('postgres',
34-
"INSERT INTO tab_int VALUES (generate_series(11,20))");
35-
sleep 1;
36-
37-
# Here we should have only 10 rows
38-
my $result = $node_standby->safe_psql('postgres', "SELECT count(*) FROM tab_int");
39-
is($result, qq(10), 'check content with delay of 1s');
40+
"INSERT INTO tab_int VALUES (generate_series(11, 20))");
4041

41-
# Now wait for replay to complete on standby
42+
# Now wait for replay to complete on standby. We're done waiting when the
43+
# slave has replayed up to the previously saved master LSN.
4244
my $until_lsn =
43-
$node_master->safe_psql('postgres', "SELECT pg_current_xlog_location();");
44-
my $caughtup_query =
45-
"SELECT '$until_lsn'::pg_lsn <= pg_last_xlog_replay_location()";
46-
$node_standby->poll_query_until('postgres', $caughtup_query)
47-
or die "Timed out while waiting for standby to catch up";
48-
$result = $node_standby->safe_psql('postgres', "SELECT count(*) FROM tab_int");
49-
is($result, qq(20), 'check content with delay of 2s');
45+
$node_master->safe_psql('postgres', "SELECT pg_current_xlog_location()");
46+
47+
my $remaining = 90;
48+
while ($remaining-- > 0)
49+
{
50+
# Done waiting?
51+
my $replay_status =
52+
$node_standby->safe_psql('postgres',
53+
"SELECT (pg_last_xlog_replay_location() - '$until_lsn'::pg_lsn) >= 0");
54+
last if $replay_status eq 't';
55+
56+
# No, sleep some more.
57+
my $sleep = $master_insert_time + $delay - time();
58+
$sleep = 1 if $sleep < 1;
59+
sleep $sleep;
60+
}
61+
62+
die "Maximum number of attempts reached ($remaining remain)" if $remaining < 0;
63+
64+
# This test is successful if and only if the LSN has been applied with at least
65+
# the configured apply delay.
66+
ok(time() - $master_insert_time >= $delay,
67+
"Check that standby applies WAL only after replication delay");

0 commit comments

Comments
 (0)