Skip to content

Commit d0b6aca

Browse files
nmischmichaelpq
authored andcommitted
Remove XLogFileInit() ability to unlink a pre-existing file.
Only initdb used it. initdb refuses to operate on a non-empty directory and generally does not cope with pre-existing files of other kinds. Hence, use the opportunity to simplify. This commit has been applied as of 421484f in v15 and newer versions. This is required on stable branches of v13 and v14 to fix a regression reported by Noah Misch, introduced by 1f95181, causing spurious failures in archive recovery (neither streaming nor archive recovery) with concurrent restartpoints. The backpatched versions of the patches have been aligned on these branches by me, Noah Misch is the author. Tests have been conducted by the both of us. Reported-by: Arun Thirupathi Author: Noah Misch <noah@leadboat.com> Discussion: https://postgr.es/m/20210202151416.GB3304930@rfd.leadboat.com Discussion: https://postgr.es/m/20250306193013.36.nmisch@google.com Backpatch-through: 13
1 parent 20e5ef3 commit d0b6aca

File tree

3 files changed

+28
-39
lines changed

3 files changed

+28
-39
lines changed

src/backend/access/transam/xlog.c

+25-36
Original file line numberDiff line numberDiff line change
@@ -2440,7 +2440,7 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
24402440
bool ispartialpage;
24412441
bool last_iteration;
24422442
bool finishing_seg;
2443-
bool use_existent;
2443+
bool added;
24442444
int curridx;
24452445
int npages;
24462446
int startidx;
@@ -2507,8 +2507,7 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
25072507
wal_segment_size);
25082508

25092509
/* create/use new log file */
2510-
use_existent = true;
2511-
openLogFile = XLogFileInit(openLogSegNo, &use_existent);
2510+
openLogFile = XLogFileInit(openLogSegNo, &added);
25122511
ReserveExternalFD();
25132512
}
25142513

@@ -3258,9 +3257,7 @@ XLogNeedsFlush(XLogRecPtr record)
32583257
*
32593258
* logsegno: identify segment to be created/opened.
32603259
*
3261-
* *use_existent: if true, OK to use a pre-existing file (else, any
3262-
* pre-existing file will be deleted). On return, false iff this call added
3263-
* some segment on disk.
3260+
* *added: on return, true if this call raised the number of extant segments.
32643261
*
32653262
* Returns FD of opened file.
32663263
*
@@ -3270,7 +3267,7 @@ XLogNeedsFlush(XLogRecPtr record)
32703267
* in a critical section.
32713268
*/
32723269
int
3273-
XLogFileInit(XLogSegNo logsegno, bool *use_existent)
3270+
XLogFileInit(XLogSegNo logsegno, bool *added)
32743271
{
32753272
char path[MAXPGPATH];
32763273
char tmppath[MAXPGPATH];
@@ -3286,19 +3283,17 @@ XLogFileInit(XLogSegNo logsegno, bool *use_existent)
32863283
/*
32873284
* Try to use existent file (checkpoint maker may have created it already)
32883285
*/
3289-
if (*use_existent)
3286+
*added = false;
3287+
fd = BasicOpenFile(path, O_RDWR | PG_BINARY | get_sync_bit(sync_method));
3288+
if (fd < 0)
32903289
{
3291-
fd = BasicOpenFile(path, O_RDWR | PG_BINARY | get_sync_bit(sync_method));
3292-
if (fd < 0)
3293-
{
3294-
if (errno != ENOENT)
3295-
ereport(ERROR,
3296-
(errcode_for_file_access(),
3297-
errmsg("could not open file \"%s\": %m", path)));
3298-
}
3299-
else
3300-
return fd;
3290+
if (errno != ENOENT)
3291+
ereport(ERROR,
3292+
(errcode_for_file_access(),
3293+
errmsg("could not open file \"%s\": %m", path)));
33013294
}
3295+
else
3296+
return fd;
33023297

33033298
/*
33043299
* Initialize an empty (all zeroes) segment. NOTE: it is possible that
@@ -3395,12 +3390,9 @@ XLogFileInit(XLogSegNo logsegno, bool *use_existent)
33953390
errmsg("could not close file \"%s\": %m", tmppath)));
33963391

33973392
/*
3398-
* Now move the segment into place with its final name.
3399-
*
3400-
* If caller didn't want to use a pre-existing file, get rid of any
3401-
* pre-existing file. Otherwise, cope with possibility that someone else
3402-
* has created the file while we were filling ours: if so, use ours to
3403-
* pre-create a future log segment.
3393+
* Now move the segment into place with its final name. Cope with
3394+
* possibility that someone else has created the file while we were
3395+
* filling ours: if so, use ours to pre-create a future log segment.
34043396
*/
34053397
installed_segno = logsegno;
34063398

@@ -3414,9 +3406,8 @@ XLogFileInit(XLogSegNo logsegno, bool *use_existent)
34143406
* CheckPointSegments.
34153407
*/
34163408
max_segno = logsegno + CheckPointSegments;
3417-
if (InstallXLogFileSegment(&installed_segno, tmppath,
3418-
*use_existent, max_segno))
3419-
*use_existent = false;
3409+
if (InstallXLogFileSegment(&installed_segno, tmppath, true, max_segno))
3410+
*added = true;
34203411
else
34213412
{
34223413
/*
@@ -3901,18 +3892,17 @@ PreallocXlogFiles(XLogRecPtr endptr)
39013892
{
39023893
XLogSegNo _logSegNo;
39033894
int lf;
3904-
bool use_existent;
3895+
bool added;
39053896
uint64 offset;
39063897

39073898
XLByteToPrevSeg(endptr, _logSegNo, wal_segment_size);
39083899
offset = XLogSegmentOffset(endptr - 1, wal_segment_size);
39093900
if (offset >= (uint32) (0.75 * wal_segment_size))
39103901
{
39113902
_logSegNo++;
3912-
use_existent = true;
3913-
lf = XLogFileInit(_logSegNo, &use_existent);
3903+
lf = XLogFileInit(_logSegNo, &added);
39143904
close(lf);
3915-
if (!use_existent)
3905+
if (added)
39163906
CheckpointStats.ckpt_segs_added++;
39173907
}
39183908
}
@@ -5225,7 +5215,7 @@ BootStrapXLOG(void)
52255215
XLogLongPageHeader longpage;
52265216
XLogRecord *record;
52275217
char *recptr;
5228-
bool use_existent;
5218+
bool added;
52295219
uint64 sysidentifier;
52305220
struct timeval tv;
52315221
pg_crc32c crc;
@@ -5322,8 +5312,7 @@ BootStrapXLOG(void)
53225312
record->xl_crc = crc;
53235313

53245314
/* Create first XLOG segment file */
5325-
use_existent = false;
5326-
openLogFile = XLogFileInit(1, &use_existent);
5315+
openLogFile = XLogFileInit(1, &added);
53275316

53285317
/*
53295318
* We needn't bother with Reserve/ReleaseExternalFD here, since we'll
@@ -5629,10 +5618,10 @@ exitArchiveRecovery(TimeLineID endTLI, XLogRecPtr endOfLog)
56295618
* The switch happened at a segment boundary, so just create the next
56305619
* segment on the new timeline.
56315620
*/
5632-
bool use_existent = true;
5621+
bool added;
56335622
int fd;
56345623

5635-
fd = XLogFileInit(startLogSegNo, &use_existent);
5624+
fd = XLogFileInit(startLogSegNo, &added);
56365625

56375626
if (close(fd) != 0)
56385627
{

src/backend/replication/walreceiver.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -918,11 +918,11 @@ XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr)
918918

919919
if (recvFile < 0)
920920
{
921-
bool use_existent = true;
921+
bool added = true;
922922

923923
/* Create/use new log file */
924924
XLByteToSeg(recptr, recvSegNo, wal_segment_size);
925-
recvFile = XLogFileInit(recvSegNo, &use_existent);
925+
recvFile = XLogFileInit(recvSegNo, &added);
926926
recvFileTLI = ThisTimeLineID;
927927
}
928928

src/include/access/xlog.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ extern XLogRecPtr XLogInsertRecord(struct XLogRecData *rdata,
286286
extern void XLogFlush(XLogRecPtr RecPtr);
287287
extern bool XLogBackgroundFlush(void);
288288
extern bool XLogNeedsFlush(XLogRecPtr RecPtr);
289-
extern int XLogFileInit(XLogSegNo segno, bool *use_existent);
289+
extern int XLogFileInit(XLogSegNo segno, bool *added);
290290
extern int XLogFileOpen(XLogSegNo segno);
291291

292292
extern void CheckXLogRemoved(XLogSegNo segno, TimeLineID tli);

0 commit comments

Comments
 (0)