|
1 | 1 |
|
2 | 2 | # Copyright (c) 2021, PostgreSQL Global Development Group
|
3 | 3 |
|
4 |
| -# Checks for recovery_min_apply_delay |
| 4 | +# Checks for recovery_min_apply_delay and recovery pause |
5 | 5 | use strict;
|
6 | 6 | use warnings;
|
7 | 7 |
|
8 | 8 | use PostgresNode;
|
9 | 9 | use TestLib;
|
10 |
| -use Test::More tests => 1; |
| 10 | +use Test::More tests => 3; |
11 | 11 |
|
12 | 12 | # Initialize primary node
|
13 | 13 | my $node_primary = get_new_node('primary');
|
|
55 | 55 | # the configured apply delay.
|
56 | 56 | ok(time() - $primary_insert_time >= $delay,
|
57 | 57 | "standby applies WAL only after replication delay");
|
| 58 | + |
| 59 | + |
| 60 | +# Check that recovery can be paused or resumed expectedly. |
| 61 | +my $node_standby2 = get_new_node('standby2'); |
| 62 | +$node_standby2->init_from_backup($node_primary, $backup_name, |
| 63 | + has_streaming => 1); |
| 64 | +$node_standby2->start; |
| 65 | + |
| 66 | +# Recovery is not yet paused. |
| 67 | +is($node_standby2->safe_psql('postgres', |
| 68 | + "SELECT pg_get_wal_replay_pause_state()"), |
| 69 | + 'not paused', 'pg_get_wal_replay_pause_state() reports not paused'); |
| 70 | + |
| 71 | +# Request to pause recovery and wait until it's actually paused. |
| 72 | +$node_standby2->safe_psql('postgres', "SELECT pg_wal_replay_pause()"); |
| 73 | +$node_primary->safe_psql('postgres', |
| 74 | + "INSERT INTO tab_int VALUES (generate_series(21,30))"); |
| 75 | +$node_standby2->poll_query_until('postgres', |
| 76 | + "SELECT pg_get_wal_replay_pause_state() = 'paused'") |
| 77 | + or die "Timed out while waiting for recovery to be paused"; |
| 78 | + |
| 79 | +# Even if new WAL records are streamed from the primary, |
| 80 | +# recovery in the paused state doesn't replay them. |
| 81 | +my $receive_lsn = $node_standby2->safe_psql('postgres', |
| 82 | + "SELECT pg_last_wal_receive_lsn()"); |
| 83 | +my $replay_lsn = $node_standby2->safe_psql('postgres', |
| 84 | + "SELECT pg_last_wal_replay_lsn()"); |
| 85 | +$node_primary->safe_psql('postgres', |
| 86 | + "INSERT INTO tab_int VALUES (generate_series(31,40))"); |
| 87 | +$node_standby2->poll_query_until('postgres', |
| 88 | + "SELECT '$receive_lsn'::pg_lsn < pg_last_wal_receive_lsn()") |
| 89 | + or die "Timed out while waiting for new WAL to be streamed"; |
| 90 | +is($node_standby2->safe_psql('postgres', |
| 91 | + "SELECT pg_last_wal_replay_lsn()"), |
| 92 | + qq($replay_lsn), 'no WAL is replayed in the paused state'); |
| 93 | + |
| 94 | +# Request to resume recovery and wait until it's actually resumed. |
| 95 | +$node_standby2->safe_psql('postgres', "SELECT pg_wal_replay_resume()"); |
| 96 | +$node_standby2->poll_query_until('postgres', |
| 97 | + "SELECT pg_get_wal_replay_pause_state() = 'not paused' AND pg_last_wal_replay_lsn() > '$replay_lsn'::pg_lsn") |
| 98 | + or die "Timed out while waiting for recovery to be resumed"; |
| 99 | + |
| 100 | +# Check that the paused state ends and promotion continues if a promotion |
| 101 | +# is triggered while recovery is paused. |
| 102 | +$node_standby2->safe_psql('postgres', "SELECT pg_wal_replay_pause()"); |
| 103 | +$node_primary->safe_psql('postgres', |
| 104 | + "INSERT INTO tab_int VALUES (generate_series(41,50))"); |
| 105 | +$node_standby2->poll_query_until('postgres', |
| 106 | + "SELECT pg_get_wal_replay_pause_state() = 'paused'") |
| 107 | + or die "Timed out while waiting for recovery to be paused"; |
| 108 | + |
| 109 | +$node_standby2->promote; |
| 110 | +$node_standby2->poll_query_until('postgres', |
| 111 | + "SELECT NOT pg_is_in_recovery()") |
| 112 | + or die "Timed out while waiting for promotion to finish"; |
0 commit comments