|
1 | 1 | # Checks for recovery_min_apply_delay
|
2 | 2 | use strict;
|
3 | 3 | use warnings;
|
| 4 | + |
4 | 5 | use PostgresNode;
|
5 | 6 | use TestLib;
|
6 |
| -use Test::More tests => 2; |
| 7 | +use Test::More tests => 1; |
7 | 8 |
|
8 | 9 | # Initialize master node
|
9 | 10 | my $node_master = get_new_node('master');
|
|
12 | 13 |
|
13 | 14 | # And some content
|
14 | 15 | $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"); |
16 | 17 |
|
17 | 18 | # Take backup
|
18 | 19 | my $backup_name = 'my_backup';
|
19 | 20 | $node_master->backup($backup_name);
|
20 | 21 |
|
21 | 22 | # Create streaming standby from backup
|
22 | 23 | my $node_standby = get_new_node('standby');
|
| 24 | +my $delay = 3; |
23 | 25 | $node_standby->init_from_backup($node_master, $backup_name,
|
24 | 26 | has_streaming => 1);
|
25 | 27 | $node_standby->append_conf(
|
26 | 28 | 'recovery.conf', qq(
|
27 |
| -recovery_min_apply_delay = '2s' |
| 29 | +recovery_min_apply_delay = '${delay}s' |
28 | 30 | ));
|
29 | 31 | $node_standby->start;
|
30 | 32 |
|
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(); |
33 | 39 | $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))"); |
40 | 41 |
|
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. |
42 | 44 | 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