1 # Minimal test testing synchronous replication sync_state transition
6 use Test::More tests => 11;
8 # Query checking sync_priority and sync_state of each standby
10 "SELECT application_name, sync_priority, sync_state FROM pg_stat_replication ORDER BY application_name;";
12 # Check that sync_state of each standby is expected (waiting till it is).
13 # If $setting is given, synchronous_standby_names is set to it and
14 # the configuration file is reloaded before the test.
17 my ($self, $expected, $msg, $setting) = @_;
19 if (defined($setting))
21 $self->psql('postgres',
22 "ALTER SYSTEM SET synchronous_standby_names = '$setting';");
26 ok($self->poll_query_until('postgres', $check_sql, $expected), $msg);
30 # Initialize master node
31 my $node_master = get_new_node('master');
32 $node_master->init(allows_streaming => 1);
34 my $backup_name = 'master_backup';
37 $node_master->backup($backup_name);
39 # Create standby1 linking to master
40 my $node_standby_1 = get_new_node('standby1');
41 $node_standby_1->init_from_backup($node_master, $backup_name,
43 $node_standby_1->start;
45 # Create standby2 linking to master
46 my $node_standby_2 = get_new_node('standby2');
47 $node_standby_2->init_from_backup($node_master, $backup_name,
49 $node_standby_2->start;
51 # Create standby3 linking to master
52 my $node_standby_3 = get_new_node('standby3');
53 $node_standby_3->init_from_backup($node_master, $backup_name,
55 $node_standby_3->start;
57 # Check that sync_state is determined correctly when
58 # synchronous_standby_names is specified in old syntax.
60 $node_master, qq(standby1|1|sync
63 'old syntax of synchronous_standby_names',
66 # Check that all the standbys are considered as either sync or
67 # potential when * is specified in synchronous_standby_names.
68 # Note that standby1 is chosen as sync standby because
69 # it's stored in the head of WalSnd array which manages
70 # all the standbys though they have the same priority.
72 $node_master, qq(standby1|1|sync
74 standby3|1|potential),
75 'asterisk in synchronous_standby_names',
78 # Stop and start standbys to rearrange the order of standbys
79 # in WalSnd array. Now, if standbys have the same priority,
80 # standby2 is selected preferentially and standby3 is next.
81 $node_standby_1->stop;
82 $node_standby_2->stop;
83 $node_standby_3->stop;
85 $node_standby_2->start;
86 $node_standby_3->start;
88 # Specify 2 as the number of sync standbys.
89 # Check that two standbys are in 'sync' state.
91 $node_master, qq(standby2|2|sync
93 '2 synchronous standbys',
94 '2(standby1,standby2,standby3)');
97 $node_standby_1->start;
99 # Create standby4 linking to master
100 my $node_standby_4 = get_new_node('standby4');
101 $node_standby_4->init_from_backup($node_master, $backup_name,
103 $node_standby_4->start;
105 # Check that standby1 and standby2 whose names appear earlier in
106 # synchronous_standby_names are considered as sync. Also check that
107 # standby3 appearing later represents potential, and standby4 is
108 # in 'async' state because it's not in the list.
110 $node_master, qq(standby1|1|sync
114 '2 sync, 1 potential, and 1 async');
116 # Check that sync_state of each standby is determined correctly
117 # when num_sync exceeds the number of names of potential sync standbys
118 # specified in synchronous_standby_names.
120 $node_master, qq(standby1|0|async
124 'num_sync exceeds the num of potential sync standbys',
125 '6(standby4,standby0,standby3,standby2)');
127 # The setting that * comes before another standby name is acceptable
128 # but does not make sense in most cases. Check that sync_state is
129 # chosen properly even in case of that setting.
130 # The priority of standby2 should be 2 because it matches * first.
132 $node_master, qq(standby1|1|sync
135 standby4|2|potential),
136 'asterisk comes before another standby name',
137 '2(standby1,*,standby2)');
139 # Check that the setting of '2(*)' chooses standby2 and standby3 that are stored
140 # earlier in WalSnd array as sync standbys.
142 $node_master, qq(standby1|1|potential
145 standby4|1|potential),
146 'multiple standbys having the same priority are chosen as sync',
149 # Stop Standby3 which is considered in 'sync' state.
150 $node_standby_3->stop;
152 # Check that the state of standby1 stored earlier in WalSnd array than
153 # standby4 is transited from potential to sync.
155 $node_master, qq(standby1|1|sync
157 standby4|1|potential),
158 'potential standby found earlier in array is promoted to sync');
160 # Check that standby1 and standby2 are chosen as sync standbys
161 # based on their priorities.
163 $node_master, qq(standby1|1|sync
166 'priority-based sync replication specified by FIRST keyword',
167 'FIRST 2(standby1, standby2)');
169 # Check that all the listed standbys are considered as candidates
170 # for sync standbys in a quorum-based sync replication.
172 $node_master, qq(standby1|1|quorum
175 '2 quorum and 1 async',
176 'ANY 2(standby1, standby2)');
178 # Start Standby3 which will be considered in 'quorum' state.
179 $node_standby_3->start;
181 # Check that the setting of 'ANY 2(*)' chooses all standbys as
182 # candidates for quorum sync standbys.
184 $node_master, qq(standby1|1|quorum
188 'all standbys are considered as candidates for quorum sync standbys',