Skip to content

Commit df8ec96

Browse files
nmischmichaelpq
authored andcommitted
Remove XLogFileInit() ability to skip ControlFileLock.
Cold paths, initdb and end-of-recovery, used it. Don't optimize them. This commit has been applied as of c53c6b9 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 e276b58 commit df8ec96

File tree

3 files changed

+16
-34
lines changed

3 files changed

+16
-34
lines changed

src/backend/access/transam/xlog.c

+14-32
Original file line numberDiff line numberDiff line change
@@ -917,8 +917,7 @@ static void AdvanceXLInsertBuffer(XLogRecPtr upto, bool opportunistic);
917917
static bool XLogCheckpointNeeded(XLogSegNo new_segno);
918918
static void XLogWrite(XLogwrtRqst WriteRqst, bool flexible);
919919
static bool InstallXLogFileSegment(XLogSegNo *segno, char *tmppath,
920-
bool find_free, XLogSegNo max_segno,
921-
bool use_lock);
920+
bool find_free, XLogSegNo max_segno);
922921
static int XLogFileRead(XLogSegNo segno, int emode, TimeLineID tli,
923922
XLogSource source, bool notfoundOk);
924923
static int XLogFileReadAnyTLI(XLogSegNo segno, int emode, XLogSource source);
@@ -2509,7 +2508,7 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
25092508

25102509
/* create/use new log file */
25112510
use_existent = true;
2512-
openLogFile = XLogFileInit(openLogSegNo, &use_existent, true);
2511+
openLogFile = XLogFileInit(openLogSegNo, &use_existent);
25132512
ReserveExternalFD();
25142513
}
25152514

@@ -3263,10 +3262,6 @@ XLogNeedsFlush(XLogRecPtr record)
32633262
* pre-existing file will be deleted). On return, true if a pre-existing
32643263
* file was used.
32653264
*
3266-
* use_lock: if true, acquire ControlFileLock while moving file into
3267-
* place. This should be true except during bootstrap log creation. The
3268-
* caller must *not* hold the lock at call.
3269-
*
32703265
* Returns FD of opened file.
32713266
*
32723267
* Note: errors here are ERROR not PANIC because we might or might not be
@@ -3275,7 +3270,7 @@ XLogNeedsFlush(XLogRecPtr record)
32753270
* in a critical section.
32763271
*/
32773272
int
3278-
XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock)
3273+
XLogFileInit(XLogSegNo logsegno, bool *use_existent)
32793274
{
32803275
char path[MAXPGPATH];
32813276
char tmppath[MAXPGPATH];
@@ -3420,8 +3415,7 @@ XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock)
34203415
*/
34213416
max_segno = logsegno + CheckPointSegments;
34223417
if (!InstallXLogFileSegment(&installed_segno, tmppath,
3423-
*use_existent, max_segno,
3424-
use_lock))
3418+
*use_existent, max_segno))
34253419
{
34263420
/*
34273421
* No need for any more future segments, or InstallXLogFileSegment()
@@ -3578,7 +3572,7 @@ XLogFileCopy(XLogSegNo destsegno, TimeLineID srcTLI, XLogSegNo srcsegno,
35783572
/*
35793573
* Now move the segment into place with its final name.
35803574
*/
3581-
if (!InstallXLogFileSegment(&destsegno, tmppath, false, 0, false))
3575+
if (!InstallXLogFileSegment(&destsegno, tmppath, false, 0))
35823576
elog(ERROR, "InstallXLogFileSegment should not have failed");
35833577
}
35843578

@@ -3602,29 +3596,20 @@ XLogFileCopy(XLogSegNo destsegno, TimeLineID srcTLI, XLogSegNo srcsegno,
36023596
* free slot is found between *segno and max_segno. (Ignored when find_free
36033597
* is false.)
36043598
*
3605-
* use_lock: if true, acquire ControlFileLock while moving file into
3606-
* place. This should be true except during bootstrap log creation. The
3607-
* caller must *not* hold the lock at call.
3608-
*
36093599
* Returns true if the file was installed successfully. false indicates that
36103600
* max_segno limit was exceeded, or an error occurred while renaming the
36113601
* file into place.
36123602
*/
36133603
static bool
36143604
InstallXLogFileSegment(XLogSegNo *segno, char *tmppath,
3615-
bool find_free, XLogSegNo max_segno,
3616-
bool use_lock)
3605+
bool find_free, XLogSegNo max_segno)
36173606
{
36183607
char path[MAXPGPATH];
36193608
struct stat stat_buf;
36203609

36213610
XLogFilePath(path, ThisTimeLineID, *segno, wal_segment_size);
36223611

3623-
/*
3624-
* We want to be sure that only one process does this at a time.
3625-
*/
3626-
if (use_lock)
3627-
LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
3612+
LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
36283613

36293614
if (!find_free)
36303615
{
@@ -3639,8 +3624,7 @@ InstallXLogFileSegment(XLogSegNo *segno, char *tmppath,
36393624
if ((*segno) >= max_segno)
36403625
{
36413626
/* Failed to find a free slot within specified range */
3642-
if (use_lock)
3643-
LWLockRelease(ControlFileLock);
3627+
LWLockRelease(ControlFileLock);
36443628
return false;
36453629
}
36463630
(*segno)++;
@@ -3651,14 +3635,12 @@ InstallXLogFileSegment(XLogSegNo *segno, char *tmppath,
36513635
Assert(access(path, F_OK) != 0 && errno == ENOENT);
36523636
if (durable_rename(tmppath, path, LOG) != 0)
36533637
{
3654-
if (use_lock)
3655-
LWLockRelease(ControlFileLock);
3638+
LWLockRelease(ControlFileLock);
36563639
/* durable_rename already emitted log message */
36573640
return false;
36583641
}
36593642

3660-
if (use_lock)
3661-
LWLockRelease(ControlFileLock);
3643+
LWLockRelease(ControlFileLock);
36623644

36633645
return true;
36643646
}
@@ -3929,7 +3911,7 @@ PreallocXlogFiles(XLogRecPtr endptr)
39293911
{
39303912
_logSegNo++;
39313913
use_existent = true;
3932-
lf = XLogFileInit(_logSegNo, &use_existent, true);
3914+
lf = XLogFileInit(_logSegNo, &use_existent);
39333915
close(lf);
39343916
if (!use_existent)
39353917
CheckpointStats.ckpt_segs_added++;
@@ -4206,7 +4188,7 @@ RemoveXlogFile(const char *segname, XLogRecPtr lastredoptr, XLogRecPtr endptr)
42064188
endlogSegNo <= recycleSegNo &&
42074189
lstat(path, &statbuf) == 0 && S_ISREG(statbuf.st_mode) &&
42084190
InstallXLogFileSegment(&endlogSegNo, path,
4209-
true, recycleSegNo, true))
4191+
true, recycleSegNo))
42104192
{
42114193
ereport(DEBUG2,
42124194
(errmsg("recycled write-ahead log file \"%s\"",
@@ -5342,7 +5324,7 @@ BootStrapXLOG(void)
53425324

53435325
/* Create first XLOG segment file */
53445326
use_existent = false;
5345-
openLogFile = XLogFileInit(1, &use_existent, false);
5327+
openLogFile = XLogFileInit(1, &use_existent);
53465328

53475329
/*
53485330
* We needn't bother with Reserve/ReleaseExternalFD here, since we'll
@@ -5651,7 +5633,7 @@ exitArchiveRecovery(TimeLineID endTLI, XLogRecPtr endOfLog)
56515633
bool use_existent = true;
56525634
int fd;
56535635

5654-
fd = XLogFileInit(startLogSegNo, &use_existent, true);
5636+
fd = XLogFileInit(startLogSegNo, &use_existent);
56555637

56565638
if (close(fd) != 0)
56575639
{

src/backend/replication/walreceiver.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -922,7 +922,7 @@ XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr)
922922

923923
/* Create/use new log file */
924924
XLByteToSeg(recptr, recvSegNo, wal_segment_size);
925-
recvFile = XLogFileInit(recvSegNo, &use_existent, true);
925+
recvFile = XLogFileInit(recvSegNo, &use_existent);
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, bool use_lock);
289+
extern int XLogFileInit(XLogSegNo segno, bool *use_existent);
290290
extern int XLogFileOpen(XLogSegNo segno);
291291

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

0 commit comments

Comments
 (0)