@@ -2424,7 +2424,6 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
24242424bool ispartialpage ;
24252425bool last_iteration ;
24262426bool finishing_seg ;
2427- bool added ;
24282427int curridx ;
24292428int npages ;
24302429int startidx ;
@@ -2490,7 +2489,7 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
24902489wal_segment_size );
24912490
24922491/* create/use new log file */
2493- openLogFile = XLogFileInit (openLogSegNo , & added );
2492+ openLogFile = XLogFileInit (openLogSegNo );
24942493ReserveExternalFD ();
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 ];
32753272char tmppath [MAXPGPATH ];
32763273PGAlignedXLogBlock zbuffer ;
32773274XLogSegNo installed_segno ;
@@ -3424,26 +3421,53 @@ XLogFileInit(XLogSegNo logsegno, bool *added)
34243421 */
34253422max_segno = logsegno + CheckPointSegments ;
34263423if (InstallXLogFileSegment (& installed_segno ,tmppath , true,max_segno ))
3424+ {
34273425* added = true;
3426+ elog (DEBUG2 ,"done creating and filling new WAL file" );
3427+ }
34283428else
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 filebelow will fail.
3432+ * failed to rename the file into place. If the rename failed,a
3433+ *caller opening the filemay fail.
34343434 */
34353435unlink (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) */
34393466fd = BasicOpenFile (path ,O_RDWR |PG_BINARY |get_sync_bit (sync_method ));
34403467if (fd < 0 )
34413468ereport (ERROR ,
34423469(errcode_for_file_access (),
34433470errmsg ("could not open file \"%s\": %m" ,path )));
3444-
3445- elog (DEBUG2 ,"done creating and filling new WAL file" );
3446-
34473471return 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{
39103943XLogSegNo _logSegNo ;
39113944int lf ;
39123945bool added ;
3946+ char path [MAXPGPATH ];
39133947uint64 offset ;
39143948
39153949XLByteToPrevSeg (endptr ,_logSegNo ,wal_segment_size );
39163950offset = XLogSegmentOffset (endptr - 1 ,wal_segment_size );
39173951if (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 );
39223957if (added )
39233958CheckpointStats .ckpt_segs_added ++ ;
39243959}
@@ -5214,7 +5249,6 @@ BootStrapXLOG(void)
52145249XLogLongPageHeader longpage ;
52155250XLogRecord * record ;
52165251char * recptr ;
5217- bool added ;
52185252uint64 sysidentifier ;
52195253struct timeval tv ;
52205254pg_crc32c crc ;
@@ -5311,7 +5345,7 @@ BootStrapXLOG(void)
53115345record -> 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 ;
56215654int fd ;
56225655
5623- fd = XLogFileInit (startLogSegNo , & added );
5656+ fd = XLogFileInit (startLogSegNo );
56245657
56255658if (close (fd )!= 0 )
56265659{