@@ -2424,7 +2424,6 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
2424
2424
bool ispartialpage ;
2425
2425
bool last_iteration ;
2426
2426
bool finishing_seg ;
2427
- bool added ;
2428
2427
int curridx ;
2429
2428
int npages ;
2430
2429
int startidx ;
@@ -2490,7 +2489,7 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
2490
2489
wal_segment_size );
2491
2490
2492
2491
/* create/use new log file */
2493
- openLogFile = XLogFileInit (openLogSegNo , & added );
2492
+ openLogFile = XLogFileInit (openLogSegNo );
2494
2493
ReserveExternalFD ();
2495
2494
}
2496
2495
@@ -3255,23 +3254,21 @@ XLogNeedsFlush(XLogRecPtr record)
3255
3254
}
3256
3255
3257
3256
/*
3258
- * Create a new XLOG file segment, or open a pre-existing one .
3257
+ * Try to make a given XLOG file segment exist .
3259
3258
*
3260
- * logsegno: identify segment to be created/opened .
3259
+ * logsegno: identify segment.
3261
3260
*
3262
3261
* *added: on return, true if this call raised the number of extant segments.
3263
3262
*
3264
- * Returns FD of opened file.
3263
+ * path: on return, this char[MAXPGPATH] has the path to the logsegno file.
3265
3264
*
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.)
3270
3268
*/
3271
- int
3272
- XLogFileInit (XLogSegNo logsegno , bool * added )
3269
+ static int
3270
+ XLogFileInitInternal (XLogSegNo logsegno , bool * added , char * path )
3273
3271
{
3274
- char path [MAXPGPATH ];
3275
3272
char tmppath [MAXPGPATH ];
3276
3273
PGAlignedXLogBlock zbuffer ;
3277
3274
XLogSegNo installed_segno ;
@@ -3424,26 +3421,53 @@ XLogFileInit(XLogSegNo logsegno, bool *added)
3424
3421
*/
3425
3422
max_segno = logsegno + CheckPointSegments ;
3426
3423
if (InstallXLogFileSegment (& installed_segno , tmppath , true, max_segno ))
3424
+ {
3427
3425
* added = true;
3426
+ elog (DEBUG2 , "done creating and filling new WAL file" );
3427
+ }
3428
3428
else
3429
3429
{
3430
3430
/*
3431
3431
* 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.
3434
3434
*/
3435
3435
unlink (tmppath );
3436
+ elog (DEBUG2 , "abandoned new WAL file" );
3436
3437
}
3437
3438
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
+
3438
3465
/* Now open original target segment (might not be file I just made) */
3439
3466
fd = BasicOpenFile (path , O_RDWR | PG_BINARY | get_sync_bit (sync_method ));
3440
3467
if (fd < 0 )
3441
3468
ereport (ERROR ,
3442
3469
(errcode_for_file_access (),
3443
3470
errmsg ("could not open file \"%s\": %m" , path )));
3444
-
3445
- elog (DEBUG2 , "done creating and filling new WAL file" );
3446
-
3447
3471
return fd ;
3448
3472
}
3449
3473
@@ -3903,22 +3927,33 @@ XLogFileClose(void)
3903
3927
* High-volume systems will be OK once they've built up a sufficient set of
3904
3928
* recycled log segments, but the startup transient is likely to include
3905
3929
* 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.)
3906
3939
*/
3907
3940
static void
3908
3941
PreallocXlogFiles (XLogRecPtr endptr )
3909
3942
{
3910
3943
XLogSegNo _logSegNo ;
3911
3944
int lf ;
3912
3945
bool added ;
3946
+ char path [MAXPGPATH ];
3913
3947
uint64 offset ;
3914
3948
3915
3949
XLByteToPrevSeg (endptr , _logSegNo , wal_segment_size );
3916
3950
offset = XLogSegmentOffset (endptr - 1 , wal_segment_size );
3917
3951
if (offset >= (uint32 ) (0.75 * wal_segment_size ))
3918
3952
{
3919
3953
_logSegNo ++ ;
3920
- lf = XLogFileInit (_logSegNo , & added );
3921
- close (lf );
3954
+ lf = XLogFileInitInternal (_logSegNo , & added , path );
3955
+ if (lf >= 0 )
3956
+ close (lf );
3922
3957
if (added )
3923
3958
CheckpointStats .ckpt_segs_added ++ ;
3924
3959
}
@@ -5214,7 +5249,6 @@ BootStrapXLOG(void)
5214
5249
XLogLongPageHeader longpage ;
5215
5250
XLogRecord * record ;
5216
5251
char * recptr ;
5217
- bool added ;
5218
5252
uint64 sysidentifier ;
5219
5253
struct timeval tv ;
5220
5254
pg_crc32c crc ;
@@ -5311,7 +5345,7 @@ BootStrapXLOG(void)
5311
5345
record -> xl_crc = crc ;
5312
5346
5313
5347
/* Create first XLOG segment file */
5314
- openLogFile = XLogFileInit (1 , & added );
5348
+ openLogFile = XLogFileInit (1 );
5315
5349
5316
5350
/*
5317
5351
* We needn't bother with Reserve/ReleaseExternalFD here, since we'll
@@ -5617,10 +5651,9 @@ exitArchiveRecovery(TimeLineID endTLI, XLogRecPtr endOfLog)
5617
5651
* The switch happened at a segment boundary, so just create the next
5618
5652
* segment on the new timeline.
5619
5653
*/
5620
- bool added ;
5621
5654
int fd ;
5622
5655
5623
- fd = XLogFileInit (startLogSegNo , & added );
5656
+ fd = XLogFileInit (startLogSegNo );
5624
5657
5625
5658
if (close (fd ) != 0 )
5626
5659
{
0 commit comments