]> granicus.if.org Git - postgresql/commitdiff
Fix recovery_min_apply_delay test
authorAlvaro Herrera <alvherre@alvh.no-ip.org>
Thu, 31 Mar 2016 18:41:18 +0000 (15:41 -0300)
committerAlvaro Herrera <alvherre@alvh.no-ip.org>
Thu, 31 Mar 2016 19:06:32 +0000 (16:06 -0300)
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

src/test/recovery/t/005_replay_delay.pl

index 986851b678e491cb380e43bbf7fda24cb02fc584..e38ab9dfd2f31046fc577ef2693c462e7186d887 100644 (file)
@@ -1,9 +1,10 @@
 # Checks for recovery_min_apply_delay
 use strict;
 use warnings;
+
 use PostgresNode;
 use TestLib;
-use Test::More tests => 2;
+use Test::More tests => 1;
 
 # Initialize master node
 my $node_master = get_new_node('master');
@@ -12,7 +13,7 @@ $node_master->start;
 
 # And some content
 $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
 my $backup_name = 'my_backup';
@@ -20,30 +21,47 @@ $node_master->backup($backup_name);
 
 # Create streaming standby from backup
 my $node_standby = get_new_node('standby');
+my $delay = 3;
 $node_standby->init_from_backup($node_master, $backup_name,
        has_streaming => 1);
 $node_standby->append_conf(
        'recovery.conf', qq(
-recovery_min_apply_delay = '2s'
+recovery_min_apply_delay = '${delay}s'
 ));
 $node_standby->start;
 
-# Make new content on master and check its presence in standby
-# depending on the delay of 2s applied above.
+# Make new content on master and check its presence in standby depending
+# 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',
-       "INSERT INTO tab_int VALUES (generate_series(11,20))");
-sleep 1;
-
-# Here we should have only 10 rows
-my $result = $node_standby->safe_psql('postgres', "SELECT count(*) FROM tab_int");
-is($result, qq(10), 'check content with delay of 1s');
+       "INSERT INTO tab_int VALUES (generate_series(11, 20))");
 
-# Now wait for replay to complete on standby
+# Now wait for replay to complete on standby. We're done waiting when the
+# slave has replayed up to the previously saved master LSN.
 my $until_lsn =
-  $node_master->safe_psql('postgres', "SELECT pg_current_xlog_location();");
-my $caughtup_query =
-  "SELECT '$until_lsn'::pg_lsn <= pg_last_xlog_replay_location()";
-$node_standby->poll_query_until('postgres', $caughtup_query)
-  or die "Timed out while waiting for standby to catch up";
-$result = $node_standby->safe_psql('postgres', "SELECT count(*) FROM tab_int");
-is($result, qq(20), 'check content with delay of 2s');
+  $node_master->safe_psql('postgres', "SELECT pg_current_xlog_location()");
+
+my $remaining = 90;
+while ($remaining-- > 0)
+{
+       # Done waiting?
+       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");