@@ -2440,7 +2440,6 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
2440
2440
bool ispartialpage ;
2441
2441
bool last_iteration ;
2442
2442
bool finishing_seg ;
2443
- bool added ;
2444
2443
int curridx ;
2445
2444
int npages ;
2446
2445
int startidx ;
@@ -2507,7 +2506,7 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
2507
2506
wal_segment_size );
2508
2507
2509
2508
/* create/use new log file */
2510
- openLogFile = XLogFileInit (openLogSegNo , & added );
2509
+ openLogFile = XLogFileInit (openLogSegNo );
2511
2510
ReserveExternalFD ();
2512
2511
}
2513
2512
@@ -3253,23 +3252,21 @@ XLogNeedsFlush(XLogRecPtr record)
3253
3252
}
3254
3253
3255
3254
/*
3256
- * Create a new XLOG file segment, or open a pre-existing one .
3255
+ * Try to make a given XLOG file segment exist .
3257
3256
*
3258
- * logsegno: identify segment to be created/opened .
3257
+ * logsegno: identify segment.
3259
3258
*
3260
3259
* *added: on return, true if this call raised the number of extant segments.
3261
3260
*
3262
- * Returns FD of opened file.
3261
+ * path: on return, this char[MAXPGPATH] has the path to the logsegno file.
3263
3262
*
3264
- * Note: errors here are ERROR not PANIC because we might or might not be
3265
- * inside a critical section (eg, during checkpoint there is no reason to
3266
- * take down the system on failure). They will promote to PANIC if we are
3267
- * in a critical section.
3263
+ * Returns -1 or FD of opened file. A -1 here is not an error; a caller
3264
+ * wanting an open segment should attempt to open "path", which usually will
3265
+ * succeed. (This is weird, but it's efficient for the callers.)
3268
3266
*/
3269
- int
3270
- XLogFileInit (XLogSegNo logsegno , bool * added )
3267
+ static int
3268
+ XLogFileInitInternal (XLogSegNo logsegno , bool * added , char * path )
3271
3269
{
3272
- char path [MAXPGPATH ];
3273
3270
char tmppath [MAXPGPATH ];
3274
3271
PGAlignedXLogBlock zbuffer ;
3275
3272
XLogSegNo installed_segno ;
@@ -3407,26 +3404,53 @@ XLogFileInit(XLogSegNo logsegno, bool *added)
3407
3404
*/
3408
3405
max_segno = logsegno + CheckPointSegments ;
3409
3406
if (InstallXLogFileSegment (& installed_segno , tmppath , true, max_segno ))
3407
+ {
3410
3408
* added = true;
3409
+ elog (DEBUG2 , "done creating and filling new WAL file" );
3410
+ }
3411
3411
else
3412
3412
{
3413
3413
/*
3414
3414
* No need for any more future segments, or InstallXLogFileSegment()
3415
- * failed to rename the file into place. If the rename failed, opening
3416
- * the file below will fail.
3415
+ * failed to rename the file into place. If the rename failed, a
3416
+ * caller opening the file may fail.
3417
3417
*/
3418
3418
unlink (tmppath );
3419
+ elog (DEBUG2 , "abandoned new WAL file" );
3419
3420
}
3420
3421
3422
+ return -1 ;
3423
+ }
3424
+
3425
+ /*
3426
+ * Create a new XLOG file segment, or open a pre-existing one.
3427
+ *
3428
+ * logsegno: identify segment to be created/opened.
3429
+ *
3430
+ * Returns FD of opened file.
3431
+ *
3432
+ * Note: errors here are ERROR not PANIC because we might or might not be
3433
+ * inside a critical section (eg, during checkpoint there is no reason to
3434
+ * take down the system on failure). They will promote to PANIC if we are
3435
+ * in a critical section.
3436
+ */
3437
+ int
3438
+ XLogFileInit (XLogSegNo logsegno )
3439
+ {
3440
+ bool ignore_added ;
3441
+ char path [MAXPGPATH ];
3442
+ int fd ;
3443
+
3444
+ fd = XLogFileInitInternal (logsegno , & ignore_added , path );
3445
+ if (fd >= 0 )
3446
+ return fd ;
3447
+
3421
3448
/* Now open original target segment (might not be file I just made) */
3422
3449
fd = BasicOpenFile (path , O_RDWR | PG_BINARY | get_sync_bit (sync_method ));
3423
3450
if (fd < 0 )
3424
3451
ereport (ERROR ,
3425
3452
(errcode_for_file_access (),
3426
3453
errmsg ("could not open file \"%s\": %m" , path )));
3427
-
3428
- elog (DEBUG2 , "done creating and filling new WAL file" );
3429
-
3430
3454
return fd ;
3431
3455
}
3432
3456
@@ -3883,22 +3907,33 @@ XLogFileClose(void)
3883
3907
* High-volume systems will be OK once they've built up a sufficient set of
3884
3908
* recycled log segments, but the startup transient is likely to include
3885
3909
* a lot of segment creations by foreground processes, which is not so good.
3910
+ *
3911
+ * XLogFileInitInternal() can ereport(ERROR). All known causes indicate big
3912
+ * trouble; for example, a full filesystem is one cause. The checkpoint WAL
3913
+ * and/or ControlFile updates already completed. If a RequestCheckpoint()
3914
+ * initiated the present checkpoint and an ERROR ends this function, the
3915
+ * command that called RequestCheckpoint() fails. That's not ideal, but it's
3916
+ * not worth contorting more functions to use caller-specified elevel values.
3917
+ * (With or without RequestCheckpoint(), an ERROR forestalls some inessential
3918
+ * reporting and resource reclamation.)
3886
3919
*/
3887
3920
static void
3888
3921
PreallocXlogFiles (XLogRecPtr endptr )
3889
3922
{
3890
3923
XLogSegNo _logSegNo ;
3891
3924
int lf ;
3892
3925
bool added ;
3926
+ char path [MAXPGPATH ];
3893
3927
uint64 offset ;
3894
3928
3895
3929
XLByteToPrevSeg (endptr , _logSegNo , wal_segment_size );
3896
3930
offset = XLogSegmentOffset (endptr - 1 , wal_segment_size );
3897
3931
if (offset >= (uint32 ) (0.75 * wal_segment_size ))
3898
3932
{
3899
3933
_logSegNo ++ ;
3900
- lf = XLogFileInit (_logSegNo , & added );
3901
- close (lf );
3934
+ lf = XLogFileInitInternal (_logSegNo , & added , path );
3935
+ if (lf >= 0 )
3936
+ close (lf );
3902
3937
if (added )
3903
3938
CheckpointStats .ckpt_segs_added ++ ;
3904
3939
}
@@ -5212,7 +5247,6 @@ BootStrapXLOG(void)
5212
5247
XLogLongPageHeader longpage ;
5213
5248
XLogRecord * record ;
5214
5249
char * recptr ;
5215
- bool added ;
5216
5250
uint64 sysidentifier ;
5217
5251
struct timeval tv ;
5218
5252
pg_crc32c crc ;
@@ -5309,7 +5343,7 @@ BootStrapXLOG(void)
5309
5343
record -> xl_crc = crc ;
5310
5344
5311
5345
/* Create first XLOG segment file */
5312
- openLogFile = XLogFileInit (1 , & added );
5346
+ openLogFile = XLogFileInit (1 );
5313
5347
5314
5348
/*
5315
5349
* We needn't bother with Reserve/ReleaseExternalFD here, since we'll
@@ -5615,10 +5649,9 @@ exitArchiveRecovery(TimeLineID endTLI, XLogRecPtr endOfLog)
5615
5649
* The switch happened at a segment boundary, so just create the next
5616
5650
* segment on the new timeline.
5617
5651
*/
5618
- bool added ;
5619
5652
int fd ;
5620
5653
5621
- fd = XLogFileInit (startLogSegNo , & added );
5654
+ fd = XLogFileInit (startLogSegNo );
5622
5655
5623
5656
if (close (fd ) != 0 )
5624
5657
{
0 commit comments