@@ -242,7 +242,7 @@ open_file_in_directory(const char *directory, const char *fname)
242
242
* wal segment size.
243
243
*/
244
244
static bool
245
- search_directory (const char * directory , const char * fname )
245
+ search_directory (const char * directory , const char * fname , bool ignore_format_errors )
246
246
{
247
247
int fd = -1 ;
248
248
DIR * xldir ;
@@ -286,11 +286,35 @@ search_directory(const char *directory, const char *fname)
286
286
287
287
WalSegSz = longhdr -> xlp_seg_size ;
288
288
289
+ // if we skip errors, we don't need to check the segment size
289
290
if (!IsValidWalSegSize (WalSegSz ))
291
+ {
292
+ if (!ignore_format_errors )
293
+ {
290
294
pg_fatal (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" ,
291
295
"WAL segment size must be a power of two between 1 MB and 1 GB, but the WAL file \"%s\" header specifies %d bytes" ,
292
296
WalSegSz ),
293
297
fname , WalSegSz );
298
+ }
299
+ else
300
+ {
301
+ struct stat stat ;
302
+ if (fstat (fd , & stat ) != 0 )
303
+ pg_fatal ("could not stat file \"%s\"" , fname );
304
+
305
+ WalSegSz = stat .st_size ;
306
+
307
+ // if file size is invalid, the xlogreader will fail later with some obscure error
308
+ // so better to fail here
309
+ if (!IsValidWalSegSize (WalSegSz ))
310
+ {
311
+ pg_fatal (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" ,
312
+ "WAL segment size must be a power of two between 1 MB and 1 GB, but the WAL file \"%s\" size is %d bytes" ,
313
+ WalSegSz ),
314
+ fname , WalSegSz );
315
+ }
316
+ }
317
+ }
294
318
}
295
319
else if (r < 0 )
296
320
pg_fatal ("could not read file \"%s\": %m" ,
@@ -320,37 +344,37 @@ search_directory(const char *directory, const char *fname)
320
344
* The valid target directory is returned.
321
345
*/
322
346
static char *
323
- identify_target_directory (char * directory , char * fname )
347
+ identify_target_directory (char * directory , char * fname , bool ignore_format_errors )
324
348
{
325
349
char fpath [MAXPGPATH ];
326
350
327
351
if (directory != NULL )
328
352
{
329
- if (search_directory (directory , fname ))
353
+ if (search_directory (directory , fname , ignore_format_errors ))
330
354
return pg_strdup (directory );
331
355
332
356
/* directory / XLOGDIR */
333
357
snprintf (fpath , MAXPGPATH , "%s/%s" , directory , XLOGDIR );
334
- if (search_directory (fpath , fname ))
358
+ if (search_directory (fpath , fname , ignore_format_errors ))
335
359
return pg_strdup (fpath );
336
360
}
337
361
else
338
362
{
339
363
const char * datadir ;
340
364
341
365
/* current directory */
342
- if (search_directory ("." , fname ))
366
+ if (search_directory ("." , fname , ignore_format_errors ))
343
367
return pg_strdup ("." );
344
368
/* XLOGDIR */
345
- if (search_directory (XLOGDIR , fname ))
369
+ if (search_directory (XLOGDIR , fname , ignore_format_errors ))
346
370
return pg_strdup (XLOGDIR );
347
371
348
372
datadir = getenv ("PGDATA" );
349
373
/* $PGDATA / XLOGDIR */
350
374
if (datadir != NULL )
351
375
{
352
376
snprintf (fpath , MAXPGPATH , "%s/%s" , datadir , XLOGDIR );
353
- if (search_directory (fpath , fname ))
377
+ if (search_directory (fpath , fname , ignore_format_errors ))
354
378
return pg_strdup (fpath );
355
379
}
356
380
}
@@ -1279,7 +1303,7 @@ main(int argc, char **argv)
1279
1303
pg_fatal ("could not open directory \"%s\": %m" , waldir );
1280
1304
}
1281
1305
1282
- waldir = identify_target_directory (waldir , fname );
1306
+ waldir = identify_target_directory (waldir , fname , config . ignore_format_errors );
1283
1307
fd = open_file_in_directory (waldir , fname );
1284
1308
if (fd < 0 )
1285
1309
pg_fatal ("could not open file \"%s\"" , fname );
@@ -1342,7 +1366,7 @@ main(int argc, char **argv)
1342
1366
}
1343
1367
else
1344
1368
if (!single_file )
1345
- waldir = identify_target_directory (waldir , NULL );
1369
+ waldir = identify_target_directory (waldir , NULL , config . ignore_format_errors );
1346
1370
1347
1371
/* we don't know what to print */
1348
1372
if (XLogRecPtrIsInvalid (private .startptr ) && !single_file )
@@ -1377,6 +1401,13 @@ main(int argc, char **argv)
1377
1401
}
1378
1402
else
1379
1403
{
1404
+ if (config .ignore_format_errors )
1405
+ {
1406
+ xlogreader_state -> skip_page_validation = true;
1407
+ xlogreader_state -> skip_invalid_records = true;
1408
+ xlogreader_state -> skip_lsn_checks = true;
1409
+ }
1410
+
1380
1411
/* first find a valid recptr to start from */
1381
1412
first_record = XLogFindNextRecord (xlogreader_state , private .startptr );
1382
1413
0 commit comments