@@ -2424,7 +2424,6 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
24242424 bool ispartialpage ;
24252425 bool last_iteration ;
24262426 bool finishing_seg ;
2427- bool added ;
24282427 int curridx ;
24292428 int npages ;
24302429 int startidx ;
@@ -2490,7 +2489,7 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
24902489 wal_segment_size );
24912490
24922491 /* create/use new log file */
2493- openLogFile = XLogFileInit (openLogSegNo , & added );
2492+ openLogFile = XLogFileInit (openLogSegNo );
24942493 ReserveExternalFD ();
24952494 }
24962495
@@ -3255,23 +3254,21 @@ XLogNeedsFlush(XLogRecPtr record)
32553254}
32563255
32573256/*
3258- * Create a new XLOG file segment, or open a pre-existing one .
3257+ * Try to make a given XLOG file segment exist .
32593258 *
3260- * logsegno: identify segment to be created/opened .
3259+ * logsegno: identify segment.
32613260 *
32623261 * *added: on return, true if this call raised the number of extant segments.
32633262 *
3264- * Returns FD of opened file.
3263+ * path: on return, this char[MAXPGPATH] has the path to the logsegno file.
32653264 *
3266- * Note: errors here are ERROR not PANIC because we might or might not be
3267- * inside a critical section (eg, during checkpoint there is no reason to
3268- * take down the system on failure). They will promote to PANIC if we are
3269- * in a critical section.
3265+ * Returns -1 or FD of opened file. A -1 here is not an error; a caller
3266+ * wanting an open segment should attempt to open "path", which usually will
3267+ * succeed. (This is weird, but it's efficient for the callers.)
32703268 */
3271- int
3272- XLogFileInit (XLogSegNo logsegno , bool * added )
3269+ static int
3270+ XLogFileInitInternal (XLogSegNo logsegno , bool * added , char * path )
32733271{
3274- char path [MAXPGPATH ];
32753272 char tmppath [MAXPGPATH ];
32763273 PGAlignedXLogBlock zbuffer ;
32773274 XLogSegNo installed_segno ;
@@ -3424,26 +3421,53 @@ XLogFileInit(XLogSegNo logsegno, bool *added)
34243421 */
34253422 max_segno = logsegno + CheckPointSegments ;
34263423 if (InstallXLogFileSegment (& installed_segno , tmppath , true, max_segno ))
3424+ {
34273425 * added = true;
3426+ elog (DEBUG2 , "done creating and filling new WAL file" );
3427+ }
34283428 else
34293429 {
34303430 /*
34313431 * No need for any more future segments, or InstallXLogFileSegment()
3432- * failed to rename the file into place. If the rename failed, opening
3433- * the file below will fail.
3432+ * failed to rename the file into place. If the rename failed, a
3433+ * caller opening the file may fail.
34343434 */
34353435 unlink (tmppath );
3436+ elog (DEBUG2 , "abandoned new WAL file" );
34363437 }
34373438
3439+ return -1 ;
3440+ }
3441+
3442+ /*
3443+ * Create a new XLOG file segment, or open a pre-existing one.
3444+ *
3445+ * logsegno: identify segment to be created/opened.
3446+ *
3447+ * Returns FD of opened file.
3448+ *
3449+ * Note: errors here are ERROR not PANIC because we might or might not be
3450+ * inside a critical section (eg, during checkpoint there is no reason to
3451+ * take down the system on failure). They will promote to PANIC if we are
3452+ * in a critical section.
3453+ */
3454+ int
3455+ XLogFileInit (XLogSegNo logsegno )
3456+ {
3457+ bool ignore_added ;
3458+ char path [MAXPGPATH ];
3459+ int fd ;
3460+
3461+ fd = XLogFileInitInternal (logsegno , & ignore_added , path );
3462+ if (fd >= 0 )
3463+ return fd ;
3464+
34383465 /* Now open original target segment (might not be file I just made) */
34393466 fd = BasicOpenFile (path , O_RDWR | PG_BINARY | get_sync_bit (sync_method ));
34403467 if (fd < 0 )
34413468 ereport (ERROR ,
34423469 (errcode_for_file_access (),
34433470 errmsg ("could not open file \"%s\": %m" , path )));
3444-
3445- elog (DEBUG2 , "done creating and filling new WAL file" );
3446-
34473471 return fd ;
34483472}
34493473
@@ -3903,22 +3927,33 @@ XLogFileClose(void)
39033927 * High-volume systems will be OK once they've built up a sufficient set of
39043928 * recycled log segments, but the startup transient is likely to include
39053929 * a lot of segment creations by foreground processes, which is not so good.
3930+ *
3931+ * XLogFileInitInternal() can ereport(ERROR). All known causes indicate big
3932+ * trouble; for example, a full filesystem is one cause. The checkpoint WAL
3933+ * and/or ControlFile updates already completed. If a RequestCheckpoint()
3934+ * initiated the present checkpoint and an ERROR ends this function, the
3935+ * command that called RequestCheckpoint() fails. That's not ideal, but it's
3936+ * not worth contorting more functions to use caller-specified elevel values.
3937+ * (With or without RequestCheckpoint(), an ERROR forestalls some inessential
3938+ * reporting and resource reclamation.)
39063939 */
39073940static void
39083941PreallocXlogFiles (XLogRecPtr endptr )
39093942{
39103943 XLogSegNo _logSegNo ;
39113944 int lf ;
39123945 bool added ;
3946+ char path [MAXPGPATH ];
39133947 uint64 offset ;
39143948
39153949 XLByteToPrevSeg (endptr , _logSegNo , wal_segment_size );
39163950 offset = XLogSegmentOffset (endptr - 1 , wal_segment_size );
39173951 if (offset >= (uint32 ) (0.75 * wal_segment_size ))
39183952 {
39193953 _logSegNo ++ ;
3920- lf = XLogFileInit (_logSegNo , & added );
3921- close (lf );
3954+ lf = XLogFileInitInternal (_logSegNo , & added , path );
3955+ if (lf >= 0 )
3956+ close (lf );
39223957 if (added )
39233958 CheckpointStats .ckpt_segs_added ++ ;
39243959 }
@@ -5214,7 +5249,6 @@ BootStrapXLOG(void)
52145249 XLogLongPageHeader longpage ;
52155250 XLogRecord * record ;
52165251 char * recptr ;
5217- bool added ;
52185252 uint64 sysidentifier ;
52195253 struct timeval tv ;
52205254 pg_crc32c crc ;
@@ -5311,7 +5345,7 @@ BootStrapXLOG(void)
53115345 record -> xl_crc = crc ;
53125346
53135347 /* Create first XLOG segment file */
5314- openLogFile = XLogFileInit (1 , & added );
5348+ openLogFile = XLogFileInit (1 );
53155349
53165350 /*
53175351 * We needn't bother with Reserve/ReleaseExternalFD here, since we'll
@@ -5617,10 +5651,9 @@ exitArchiveRecovery(TimeLineID endTLI, XLogRecPtr endOfLog)
56175651 * The switch happened at a segment boundary, so just create the next
56185652 * segment on the new timeline.
56195653 */
5620- bool added ;
56215654 int fd ;
56225655
5623- fd = XLogFileInit (startLogSegNo , & added );
5656+ fd = XLogFileInit (startLogSegNo );
56245657
56255658 if (close (fd ) != 0 )
56265659 {
0 commit comments