@@ -189,7 +189,7 @@ open_file_in_directory(const char *directory, const char *fname)
189
189
* wal segment size.
190
190
*/
191
191
static bool
192
- search_directory (const char * directory , const char * fname )
192
+ search_directory (const char * directory , const char * fname , bool ignore_format_errors )
193
193
{
194
194
int fd = -1 ;
195
195
DIR * xldir ;
@@ -233,11 +233,35 @@ search_directory(const char *directory, const char *fname)
233
233
234
234
WalSegSz = longhdr -> xlp_seg_size ;
235
235
236
+ // if we skip errors, we don't need to check the segment size
236
237
if (!IsValidWalSegSize (WalSegSz ))
238
+ {
239
+ if (!ignore_format_errors )
240
+ {
237
241
fatal_error (ngettext ("WAL segment size must be a power of two between 1 MB and 1 GB, but the WAL file \"%s\" header specifies %d byte" ,
238
- "WAL segment size must be a power of two between 1 MB and 1 GB, but the WAL file \"%s\" header specifies %d bytes" ,
239
- WalSegSz ),
240
- fname , WalSegSz );
242
+ "WAL segment size must be a power of two between 1 MB and 1 GB, but the WAL file \"%s\" header specifies %d bytes" ,
243
+ WalSegSz ),
244
+ fname , WalSegSz );
245
+ }
246
+ else
247
+ {
248
+ struct stat stat ;
249
+ if (fstat (fd , & stat ) != 0 )
250
+ fatal_error ("could not stat file \"%s\"" , fname );
251
+
252
+ WalSegSz = stat .st_size ;
253
+
254
+ // if file size is invalid, the xlogreader will fail later with some obscure error
255
+ // so better to fail here
256
+ if (!IsValidWalSegSize (WalSegSz ))
257
+ {
258
+ fatal_error (ngettext ("WAL segment size must be a power of two between 1 MB and 1 GB, but the WAL file \"%s\" size is %d byte" ,
259
+ "WAL segment size must be a power of two between 1 MB and 1 GB, but the WAL file \"%s\" size is %d bytes" ,
260
+ WalSegSz ),
261
+ fname , WalSegSz );
262
+ }
263
+ }
264
+ }
241
265
}
242
266
else if (r < 0 )
243
267
fatal_error ("could not read file \"%s\": %m" ,
@@ -267,37 +291,37 @@ search_directory(const char *directory, const char *fname)
267
291
* The valid target directory is returned.
268
292
*/
269
293
static char *
270
- identify_target_directory (char * directory , char * fname )
294
+ identify_target_directory (char * directory , char * fname , bool ignore_format_errors )
271
295
{
272
296
char fpath [MAXPGPATH ];
273
297
274
298
if (directory != NULL )
275
299
{
276
- if (search_directory (directory , fname ))
300
+ if (search_directory (directory , fname , ignore_format_errors ))
277
301
return pg_strdup (directory );
278
302
279
303
/* directory / XLOGDIR */
280
304
snprintf (fpath , MAXPGPATH , "%s/%s" , directory , XLOGDIR );
281
- if (search_directory (fpath , fname ))
305
+ if (search_directory (fpath , fname , ignore_format_errors ))
282
306
return pg_strdup (fpath );
283
307
}
284
308
else
285
309
{
286
310
const char * datadir ;
287
311
288
312
/* current directory */
289
- if (search_directory ("." , fname ))
313
+ if (search_directory ("." , fname , ignore_format_errors ))
290
314
return pg_strdup ("." );
291
315
/* XLOGDIR */
292
- if (search_directory (XLOGDIR , fname ))
316
+ if (search_directory (XLOGDIR , fname , ignore_format_errors ))
293
317
return pg_strdup (XLOGDIR );
294
318
295
319
datadir = getenv ("PGDATA" );
296
320
/* $PGDATA / XLOGDIR */
297
321
if (datadir != NULL )
298
322
{
299
323
snprintf (fpath , MAXPGPATH , "%s/%s" , datadir , XLOGDIR );
300
- if (search_directory (fpath , fname ))
324
+ if (search_directory (fpath , fname , ignore_format_errors ))
301
325
return pg_strdup (fpath );
302
326
}
303
327
}
@@ -1119,7 +1143,7 @@ main(int argc, char **argv)
1119
1143
fatal_error ("could not open directory \"%s\": %m" , waldir );
1120
1144
}
1121
1145
1122
- waldir = identify_target_directory (waldir , fname );
1146
+ waldir = identify_target_directory (waldir , fname , config . ignore_format_errors );
1123
1147
fd = open_file_in_directory (waldir , fname );
1124
1148
if (fd < 0 )
1125
1149
fatal_error ("could not open file \"%s\"" , fname );
@@ -1182,7 +1206,7 @@ main(int argc, char **argv)
1182
1206
}
1183
1207
else
1184
1208
if (!single_file )
1185
- waldir = identify_target_directory (waldir , NULL );
1209
+ waldir = identify_target_directory (waldir , NULL , config . ignore_format_errors );
1186
1210
1187
1211
/* we don't know what to print */
1188
1212
if (XLogRecPtrIsInvalid (private .startptr ) && !single_file )
@@ -1218,6 +1242,13 @@ main(int argc, char **argv)
1218
1242
}
1219
1243
else
1220
1244
{
1245
+ if (config .ignore_format_errors )
1246
+ {
1247
+ xlogreader_state -> skip_page_validation = true;
1248
+ xlogreader_state -> skip_invalid_records = true;
1249
+ xlogreader_state -> skip_lsn_checks = true;
1250
+ }
1251
+
1221
1252
/* first find a valid recptr to start from */
1222
1253
first_record = XLogFindNextRecord (xlogreader_state , private .startptr );
1223
1254
0 commit comments