@@ -204,7 +204,7 @@ open_file_in_directory(const char *directory, const char *fname)
204
204
* wal segment size.
205
205
*/
206
206
static bool
207
- search_directory (const char * directory , const char * fname )
207
+ search_directory (const char * directory , const char * fname , bool ignore_format_errors )
208
208
{
209
209
int fd = -1 ;
210
210
DIR * xldir ;
@@ -248,11 +248,35 @@ search_directory(const char *directory, const char *fname)
248
248
249
249
WalSegSz = longhdr -> xlp_seg_size ;
250
250
251
+ // if we skip errors, we don't need to check the segment size
251
252
if (!IsValidWalSegSize (WalSegSz ))
253
+ {
254
+ if (!ignore_format_errors )
255
+ {
252
256
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" ,
253
257
"WAL segment size must be a power of two between 1 MB and 1 GB, but the WAL file \"%s\" header specifies %d bytes" ,
254
258
WalSegSz ),
255
259
fname , WalSegSz );
260
+ }
261
+ else
262
+ {
263
+ struct stat stat ;
264
+ if (fstat (fd , & stat ) != 0 )
265
+ pg_fatal ("could not stat file \"%s\"" , fname );
266
+
267
+ WalSegSz = stat .st_size ;
268
+
269
+ // if file size is invalid, the xlogreader will fail later with some obscure error
270
+ // so better to fail here
271
+ if (!IsValidWalSegSize (WalSegSz ))
272
+ {
273
+ 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" ,
274
+ "WAL segment size must be a power of two between 1 MB and 1 GB, but the WAL file \"%s\" size is %d bytes" ,
275
+ WalSegSz ),
276
+ fname , WalSegSz );
277
+ }
278
+ }
279
+ }
256
280
}
257
281
else if (r < 0 )
258
282
pg_fatal ("could not read file \"%s\": %m" ,
@@ -282,37 +306,37 @@ search_directory(const char *directory, const char *fname)
282
306
* The valid target directory is returned.
283
307
*/
284
308
static char *
285
- identify_target_directory (char * directory , char * fname )
309
+ identify_target_directory (char * directory , char * fname , bool ignore_format_errors )
286
310
{
287
311
char fpath [MAXPGPATH ];
288
312
289
313
if (directory != NULL )
290
314
{
291
- if (search_directory (directory , fname ))
315
+ if (search_directory (directory , fname , ignore_format_errors ))
292
316
return pg_strdup (directory );
293
317
294
318
/* directory / XLOGDIR */
295
319
snprintf (fpath , MAXPGPATH , "%s/%s" , directory , XLOGDIR );
296
- if (search_directory (fpath , fname ))
320
+ if (search_directory (fpath , fname , ignore_format_errors ))
297
321
return pg_strdup (fpath );
298
322
}
299
323
else
300
324
{
301
325
const char * datadir ;
302
326
303
327
/* current directory */
304
- if (search_directory ("." , fname ))
328
+ if (search_directory ("." , fname , ignore_format_errors ))
305
329
return pg_strdup ("." );
306
330
/* XLOGDIR */
307
- if (search_directory (XLOGDIR , fname ))
331
+ if (search_directory (XLOGDIR , fname , ignore_format_errors ))
308
332
return pg_strdup (XLOGDIR );
309
333
310
334
datadir = getenv ("PGDATA" );
311
335
/* $PGDATA / XLOGDIR */
312
336
if (datadir != NULL )
313
337
{
314
338
snprintf (fpath , MAXPGPATH , "%s/%s" , datadir , XLOGDIR );
315
- if (search_directory (fpath , fname ))
339
+ if (search_directory (fpath , fname , ignore_format_errors ))
316
340
return pg_strdup (fpath );
317
341
}
318
342
}
@@ -1147,7 +1171,7 @@ main(int argc, char **argv)
1147
1171
pg_fatal ("could not open directory \"%s\": %m" , waldir );
1148
1172
}
1149
1173
1150
- waldir = identify_target_directory (waldir , fname );
1174
+ waldir = identify_target_directory (waldir , fname , config . ignore_format_errors );
1151
1175
fd = open_file_in_directory (waldir , fname );
1152
1176
if (fd < 0 )
1153
1177
pg_fatal ("could not open file \"%s\"" , fname );
@@ -1210,7 +1234,7 @@ main(int argc, char **argv)
1210
1234
}
1211
1235
else
1212
1236
if (!single_file )
1213
- waldir = identify_target_directory (waldir , NULL );
1237
+ waldir = identify_target_directory (waldir , NULL , config . ignore_format_errors );
1214
1238
1215
1239
/* we don't know what to print */
1216
1240
if (XLogRecPtrIsInvalid (private .startptr ) && !single_file )
@@ -1245,6 +1269,13 @@ main(int argc, char **argv)
1245
1269
}
1246
1270
else
1247
1271
{
1272
+ if (config .ignore_format_errors )
1273
+ {
1274
+ xlogreader_state -> skip_page_validation = true;
1275
+ xlogreader_state -> skip_invalid_records = true;
1276
+ xlogreader_state -> skip_lsn_checks = true;
1277
+ }
1278
+
1248
1279
/* first find a valid recptr to start from */
1249
1280
first_record = XLogFindNextRecord (xlogreader_state , private .startptr );
1250
1281
0 commit comments