@@ -2452,7 +2452,6 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
2452
2452
bool ispartialpage ;
2453
2453
bool last_iteration ;
2454
2454
bool finishing_seg ;
2455
- bool added ;
2456
2455
int curridx ;
2457
2456
int npages ;
2458
2457
int startidx ;
@@ -2518,7 +2517,7 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
2518
2517
wal_segment_size );
2519
2518
2520
2519
/* create/use new log file */
2521
- openLogFile = XLogFileInit (openLogSegNo , & added );
2520
+ openLogFile = XLogFileInit (openLogSegNo );
2522
2521
ReserveExternalFD ();
2523
2522
}
2524
2523
@@ -3283,23 +3282,21 @@ XLogNeedsFlush(XLogRecPtr record)
3283
3282
}
3284
3283
3285
3284
/*
3286
- * Create a new XLOG file segment, or open a pre-existing one .
3285
+ * Try to make a given XLOG file segment exist .
3287
3286
*
3288
- * logsegno: identify segment to be created/opened .
3287
+ * logsegno: identify segment.
3289
3288
*
3290
3289
* *added: on return, true if this call raised the number of extant segments.
3291
3290
*
3292
- * Returns FD of opened file.
3291
+ * path: on return, this char[MAXPGPATH] has the path to the logsegno file.
3293
3292
*
3294
- * Note: errors here are ERROR not PANIC because we might or might not be
3295
- * inside a critical section (eg, during checkpoint there is no reason to
3296
- * take down the system on failure). They will promote to PANIC if we are
3297
- * in a critical section.
3293
+ * Returns -1 or FD of opened file. A -1 here is not an error; a caller
3294
+ * wanting an open segment should attempt to open "path", which usually will
3295
+ * succeed. (This is weird, but it's efficient for the callers.)
3298
3296
*/
3299
- int
3300
- XLogFileInit (XLogSegNo logsegno , bool * added )
3297
+ static int
3298
+ XLogFileInitInternal (XLogSegNo logsegno , bool * added , char * path )
3301
3299
{
3302
- char path [MAXPGPATH ];
3303
3300
char tmppath [MAXPGPATH ];
3304
3301
PGAlignedXLogBlock zbuffer ;
3305
3302
XLogSegNo installed_segno ;
@@ -3452,26 +3449,53 @@ XLogFileInit(XLogSegNo logsegno, bool *added)
3452
3449
*/
3453
3450
max_segno = logsegno + CheckPointSegments ;
3454
3451
if (InstallXLogFileSegment (& installed_segno , tmppath , true, max_segno ))
3452
+ {
3455
3453
* added = true;
3454
+ elog (DEBUG2 , "done creating and filling new WAL file" );
3455
+ }
3456
3456
else
3457
3457
{
3458
3458
/*
3459
3459
* No need for any more future segments, or InstallXLogFileSegment()
3460
- * failed to rename the file into place. If the rename failed, opening
3461
- * the file below will fail.
3460
+ * failed to rename the file into place. If the rename failed, a
3461
+ * caller opening the file may fail.
3462
3462
*/
3463
3463
unlink (tmppath );
3464
+ elog (DEBUG2 , "abandoned new WAL file" );
3464
3465
}
3465
3466
3467
+ return -1 ;
3468
+ }
3469
+
3470
+ /*
3471
+ * Create a new XLOG file segment, or open a pre-existing one.
3472
+ *
3473
+ * logsegno: identify segment to be created/opened.
3474
+ *
3475
+ * Returns FD of opened file.
3476
+ *
3477
+ * Note: errors here are ERROR not PANIC because we might or might not be
3478
+ * inside a critical section (eg, during checkpoint there is no reason to
3479
+ * take down the system on failure). They will promote to PANIC if we are
3480
+ * in a critical section.
3481
+ */
3482
+ int
3483
+ XLogFileInit (XLogSegNo logsegno )
3484
+ {
3485
+ bool ignore_added ;
3486
+ char path [MAXPGPATH ];
3487
+ int fd ;
3488
+
3489
+ fd = XLogFileInitInternal (logsegno , & ignore_added , path );
3490
+ if (fd >= 0 )
3491
+ return fd ;
3492
+
3466
3493
/* Now open original target segment (might not be file I just made) */
3467
3494
fd = BasicOpenFile (path , O_RDWR | PG_BINARY | get_sync_bit (sync_method ));
3468
3495
if (fd < 0 )
3469
3496
ereport (ERROR ,
3470
3497
(errcode_for_file_access (),
3471
3498
errmsg ("could not open file \"%s\": %m" , path )));
3472
-
3473
- elog (DEBUG2 , "done creating and filling new WAL file" );
3474
-
3475
3499
return fd ;
3476
3500
}
3477
3501
@@ -3928,22 +3952,33 @@ XLogFileClose(void)
3928
3952
* High-volume systems will be OK once they've built up a sufficient set of
3929
3953
* recycled log segments, but the startup transient is likely to include
3930
3954
* a lot of segment creations by foreground processes, which is not so good.
3955
+ *
3956
+ * XLogFileInitInternal() can ereport(ERROR). All known causes indicate big
3957
+ * trouble; for example, a full filesystem is one cause. The checkpoint WAL
3958
+ * and/or ControlFile updates already completed. If a RequestCheckpoint()
3959
+ * initiated the present checkpoint and an ERROR ends this function, the
3960
+ * command that called RequestCheckpoint() fails. That's not ideal, but it's
3961
+ * not worth contorting more functions to use caller-specified elevel values.
3962
+ * (With or without RequestCheckpoint(), an ERROR forestalls some inessential
3963
+ * reporting and resource reclamation.)
3931
3964
*/
3932
3965
static void
3933
3966
PreallocXlogFiles (XLogRecPtr endptr )
3934
3967
{
3935
3968
XLogSegNo _logSegNo ;
3936
3969
int lf ;
3937
3970
bool added ;
3971
+ char path [MAXPGPATH ];
3938
3972
uint64 offset ;
3939
3973
3940
3974
XLByteToPrevSeg (endptr , _logSegNo , wal_segment_size );
3941
3975
offset = XLogSegmentOffset (endptr - 1 , wal_segment_size );
3942
3976
if (offset >= (uint32 ) (0.75 * wal_segment_size ))
3943
3977
{
3944
3978
_logSegNo ++ ;
3945
- lf = XLogFileInit (_logSegNo , & added );
3946
- close (lf );
3979
+ lf = XLogFileInitInternal (_logSegNo , & added , path );
3980
+ if (lf >= 0 )
3981
+ close (lf );
3947
3982
if (added )
3948
3983
CheckpointStats .ckpt_segs_added ++ ;
3949
3984
}
@@ -5258,7 +5293,6 @@ BootStrapXLOG(void)
5258
5293
XLogLongPageHeader longpage ;
5259
5294
XLogRecord * record ;
5260
5295
char * recptr ;
5261
- bool added ;
5262
5296
uint64 sysidentifier ;
5263
5297
struct timeval tv ;
5264
5298
pg_crc32c crc ;
@@ -5355,7 +5389,7 @@ BootStrapXLOG(void)
5355
5389
record -> xl_crc = crc ;
5356
5390
5357
5391
/* Create first XLOG segment file */
5358
- openLogFile = XLogFileInit (1 , & added );
5392
+ openLogFile = XLogFileInit (1 );
5359
5393
5360
5394
/*
5361
5395
* We needn't bother with Reserve/ReleaseExternalFD here, since we'll
@@ -5661,10 +5695,9 @@ exitArchiveRecovery(TimeLineID endTLI, XLogRecPtr endOfLog)
5661
5695
* The switch happened at a segment boundary, so just create the next
5662
5696
* segment on the new timeline.
5663
5697
*/
5664
- bool added ;
5665
5698
int fd ;
5666
5699
5667
- fd = XLogFileInit (startLogSegNo , & added );
5700
+ fd = XLogFileInit (startLogSegNo );
5668
5701
5669
5702
if (close (fd ) != 0 )
5670
5703
{
0 commit comments