|
10 | 10 | use TestLib; |
11 | 11 | use Test::More; |
12 | 12 |
|
13 | | -plan tests => 5; |
| 13 | +plan tests => 3; |
14 | 14 |
|
15 | 15 | # Test: Create a physical replica that's missing the last WAL file, |
16 | 16 | # then restart the primary to create a divergent WAL file and observe |
|
89 | 89 | my $log = slurp_file($node_standby->logfile); |
90 | 90 | like( |
91 | 91 | $log, |
92 | | - qr[sucessfully skipped missing contrecord at], |
| 92 | + qr[successfully skipped missing contrecord at], |
93 | 93 | "found log line in standby"); |
94 | 94 |
|
95 | 95 | $node->stop; |
96 | 96 | $node_standby->stop; |
97 | | - |
98 | | - |
99 | | -# Second test: a standby that receives WAL via archive/restore commands. |
100 | | -$node = PostgresNode->new('primary2'); |
101 | | -$node->init( |
102 | | - has_archiving => 1, |
103 | | - extra => ['--wal-segsize=1']); |
104 | | -$node->set_replication_conf; |
105 | | - |
106 | | -# Note: consistent use of forward slashes here avoids any escaping problems |
107 | | -# that arise from use of backslashes. That means we need to double-quote all |
108 | | -# the paths in the archive_command |
109 | | -my $perlbin = TestLib::perl2host($^X); |
110 | | -$perlbin =~ s!\\!/!g if $TestLib::windows_os; |
111 | | -my $archivedir = $node->archive_dir; |
112 | | -$archivedir =~ s!\\!/!g if $TestLib::windows_os; |
113 | | -$node->append_conf( |
114 | | - 'postgresql.conf', |
115 | | - qq{ |
116 | | -archive_command = '"$perlbin" "$FindBin::RealBin/idiosyncratic_copy" "%p" "$archivedir/%f"' |
117 | | -wal_level = replica |
118 | | -max_wal_senders = 2 |
119 | | -wal_keep_size = 1GB |
120 | | -}); |
121 | | -# Make sure that Msys perl doesn't complain about difficulty in setting locale |
122 | | -# when called from the archive_command. |
123 | | -local $ENV{PERL_BADLANG} = 0; |
124 | | -$node->start; |
125 | | -$node->backup('backup'); |
126 | | - |
127 | | -$node_standby = PostgresNode->new('standby2'); |
128 | | -$node_standby->init_from_backup($node, 'backup', has_restoring => 1); |
129 | | - |
130 | | -$node_standby->start; |
131 | | - |
132 | | -$node->safe_psql('postgres', 'create table filler (a int)'); |
133 | | -# First, measure how many bytes does the insertion of 1000 rows produce |
134 | | -$start_lsn = |
135 | | - $node->safe_psql('postgres', q{select pg_current_wal_insert_lsn() - '0/0'}); |
136 | | -$node->safe_psql('postgres', |
137 | | - 'insert into filler select * from generate_series(1, 1000)'); |
138 | | -$end_lsn = |
139 | | - $node->safe_psql('postgres', q{select pg_current_wal_insert_lsn() - '0/0'}); |
140 | | -$rows_walsize = $end_lsn - $start_lsn; |
141 | | - |
142 | | -# Now consume all remaining room in the current WAL segment, leaving |
143 | | -# space enough only for the start of a largish record. |
144 | | -$node->safe_psql( |
145 | | - 'postgres', qq{ |
146 | | -WITH setting AS ( |
147 | | - SELECT setting::int AS wal_segsize |
148 | | - FROM pg_settings WHERE name = 'wal_segment_size' |
149 | | -) |
150 | | -INSERT INTO filler |
151 | | -SELECT g FROM setting, |
152 | | - generate_series(1, 1000 * (wal_segsize - ((pg_current_wal_insert_lsn() - '0/0') % wal_segsize)) / $rows_walsize) g |
153 | | -}); |
154 | | - |
155 | | -# Now block idiosyncratic_copy from creating the next WAL in the replica |
156 | | -my $archivedgood = $node->safe_psql('postgres', |
157 | | - q{SELECT pg_walfile_name(pg_current_wal_insert_lsn())}); |
158 | | -my $archivedfail = $node->safe_psql( |
159 | | - 'postgres', |
160 | | - q{SELECT pg_walfile_name(pg_current_wal_insert_lsn() + setting::integer) |
161 | | - from pg_settings where name = 'wal_segment_size'}); |
162 | | -open my $filefail, ">", "$archivedir/$archivedfail.fail" |
163 | | - or die "can't open $archivedir/$archivedfail.fail: $!"; |
164 | | - |
165 | | -my $currlsn = |
166 | | - $node->safe_psql('postgres', 'select pg_current_wal_insert_lsn() - 1000'); |
167 | | - |
168 | | -# Now produce a large WAL record in a transaction that we leave open |
169 | | -my ($in, $out); |
170 | | -my $timer = IPC::Run::timeout(180); |
171 | | -my $h = |
172 | | - $node->background_psql('postgres', \$in, \$out, $timer, on_error_stop => 0); |
173 | | - |
174 | | -$in .= qq{BEGIN; |
175 | | -SELECT pg_logical_emit_message(true, 'test 026', repeat('somenoise', 8192)); |
176 | | -}; |
177 | | -$h->pump_nb; |
178 | | -$node->poll_query_until( |
179 | | - 'postgres', |
180 | | - "SELECT last_archived_wal >= '$archivedgood' FROM pg_stat_archiver"), |
181 | | - or die "Timed out while waiting for standby to catch up"; |
182 | | - |
183 | | -# Now crash the node with the transaction open |
184 | | -$node->stop('immediate'); |
185 | | -$h->finish(); |
186 | | -$node->start; |
187 | | -$node->safe_psql('postgres', 'create table witness (a int);'); |
188 | | -$node->safe_psql('postgres', 'insert into witness values (42)'); |
189 | | -unlink "$archivedir/$archivedfail.fail" |
190 | | - or die "can't unlink $archivedir/$archivedfail.fail: $!"; |
191 | | -$node->safe_psql('postgres', 'select pg_switch_wal()'); |
192 | | - |
193 | | -$until_lsn = $node->safe_psql('postgres', "SELECT pg_current_wal_lsn()"); |
194 | | -$caughtup_query = "SELECT '$until_lsn'::pg_lsn <= pg_last_wal_replay_lsn()"; |
195 | | -$node_standby->poll_query_until('postgres', $caughtup_query) |
196 | | - or die "Timed out while waiting for standby to catch up"; |
197 | | - |
198 | | -my $answer = $node_standby->safe_psql('postgres', 'select * from witness'); |
199 | | -is($answer, '42', 'witness tuple appears'); |
200 | | - |
201 | | -# Verify message appears in standby's log |
202 | | -$log = slurp_file($node_standby->logfile); |
203 | | -like( |
204 | | - $log, |
205 | | - qr[sucessfully skipped missing contrecord at], |
206 | | - "found log line in standby"); |
207 | | -$node->stop; |
208 | | -$node_standby->stop; |
0 commit comments