Skip to content

Commit 6b168c1

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 754a3d8 commit 6b168c1

File tree

3 files changed

+16
-34
lines changed

3 files changed

+16
-34
lines changed

src/backend/access/transam/xlog.c

Lines changed: 14 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -927,8 +927,7 @@ static void AdvanceXLInsertBuffer(XLogRecPtr upto, bool opportunistic);
927927
static bool XLogCheckpointNeeded(XLogSegNo new_segno);
928928
static void XLogWrite(XLogwrtRqst WriteRqst, bool flexible);
929929
static bool InstallXLogFileSegment(XLogSegNo *segno, char *tmppath,
930-
bool find_free, XLogSegNo max_segno,
931-
bool use_lock);
930+
bool find_free, XLogSegNo max_segno);
932931
static int XLogFileRead(XLogSegNo segno, int emode, TimeLineID tli,
933932
XLogSource source, bool notfoundOk);
934933
static int XLogFileReadAnyTLI(XLogSegNo segno, int emode, XLogSource source);
@@ -2520,7 +2519,7 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
25202519

25212520
/* create/use new log file */
25222521
use_existent = true;
2523-
openLogFile = XLogFileInit(openLogSegNo, &use_existent, true);
2522+
openLogFile = XLogFileInit(openLogSegNo, &use_existent);
25242523
ReserveExternalFD();
25252524
}
25262525

@@ -3293,10 +3292,6 @@ XLogNeedsFlush(XLogRecPtr record)
32933292
* pre-existing file will be deleted). On return, true if a pre-existing
32943293
* file was used.
32953294
*
3296-
* use_lock: if true, acquire ControlFileLock while moving file into
3297-
* place. This should be true except during bootstrap log creation. The
3298-
* caller must *not* hold the lock at call.
3299-
*
33003295
* Returns FD of opened file.
33013296
*
33023297
* Note: errors here are ERROR not PANIC because we might or might not be
@@ -3305,7 +3300,7 @@ XLogNeedsFlush(XLogRecPtr record)
33053300
* in a critical section.
33063301
*/
33073302
int
3308-
XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock)
3303+
XLogFileInit(XLogSegNo logsegno, bool *use_existent)
33093304
{
33103305
char path[MAXPGPATH];
33113306
char tmppath[MAXPGPATH];
@@ -3465,8 +3460,7 @@ XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock)
34653460
*/
34663461
max_segno = logsegno + CheckPointSegments;
34673462
if (!InstallXLogFileSegment(&installed_segno, tmppath,
3468-
*use_existent, max_segno,
3469-
use_lock))
3463+
*use_existent, max_segno))
34703464
{
34713465
/*
34723466
* No need for any more future segments, or InstallXLogFileSegment()
@@ -3623,7 +3617,7 @@ XLogFileCopy(XLogSegNo destsegno, TimeLineID srcTLI, XLogSegNo srcsegno,
36233617
/*
36243618
* Now move the segment into place with its final name.
36253619
*/
3626-
if (!InstallXLogFileSegment(&destsegno, tmppath, false, 0, false))
3620+
if (!InstallXLogFileSegment(&destsegno, tmppath, false, 0))
36273621
elog(ERROR, "InstallXLogFileSegment should not have failed");
36283622
}
36293623

@@ -3647,29 +3641,20 @@ XLogFileCopy(XLogSegNo destsegno, TimeLineID srcTLI, XLogSegNo srcsegno,
36473641
* free slot is found between *segno and max_segno. (Ignored when find_free
36483642
* is false.)
36493643
*
3650-
* use_lock: if true, acquire ControlFileLock while moving file into
3651-
* place. This should be true except during bootstrap log creation. The
3652-
* caller must *not* hold the lock at call.
3653-
*
36543644
* Returns true if the file was installed successfully. false indicates that
36553645
* max_segno limit was exceeded, or an error occurred while renaming the
36563646
* file into place.
36573647
*/
36583648
static bool
36593649
InstallXLogFileSegment(XLogSegNo *segno, char *tmppath,
3660-
bool find_free, XLogSegNo max_segno,
3661-
bool use_lock)
3650+
bool find_free, XLogSegNo max_segno)
36623651
{
36633652
char path[MAXPGPATH];
36643653
struct stat stat_buf;
36653654

36663655
XLogFilePath(path, ThisTimeLineID, *segno, wal_segment_size);
36673656

3668-
/*
3669-
* We want to be sure that only one process does this at a time.
3670-
*/
3671-
if (use_lock)
3672-
LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
3657+
LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
36733658

36743659
if (!find_free)
36753660
{
@@ -3684,8 +3669,7 @@ InstallXLogFileSegment(XLogSegNo *segno, char *tmppath,
36843669
if ((*segno) >= max_segno)
36853670
{
36863671
/* Failed to find a free slot within specified range */
3687-
if (use_lock)
3688-
LWLockRelease(ControlFileLock);
3672+
LWLockRelease(ControlFileLock);
36893673
return false;
36903674
}
36913675
(*segno)++;
@@ -3696,14 +3680,12 @@ InstallXLogFileSegment(XLogSegNo *segno, char *tmppath,
36963680
Assert(access(path, F_OK) != 0 && errno == ENOENT);
36973681
if (durable_rename(tmppath, path, LOG) != 0)
36983682
{
3699-
if (use_lock)
3700-
LWLockRelease(ControlFileLock);
3683+
LWLockRelease(ControlFileLock);
37013684
/* durable_rename already emitted log message */
37023685
return false;
37033686
}
37043687

3705-
if (use_lock)
3706-
LWLockRelease(ControlFileLock);
3688+
LWLockRelease(ControlFileLock);
37073689

37083690
return true;
37093691
}
@@ -3974,7 +3956,7 @@ PreallocXlogFiles(XLogRecPtr endptr)
39743956
{
39753957
_logSegNo++;
39763958
use_existent = true;
3977-
lf = XLogFileInit(_logSegNo, &use_existent, true);
3959+
lf = XLogFileInit(_logSegNo, &use_existent);
39783960
close(lf);
39793961
if (!use_existent)
39803962
CheckpointStats.ckpt_segs_added++;
@@ -4251,7 +4233,7 @@ RemoveXlogFile(const char *segname, XLogSegNo recycleSegNo,
42514233
*endlogSegNo <= recycleSegNo &&
42524234
lstat(path, &statbuf) == 0 && S_ISREG(statbuf.st_mode) &&
42534235
InstallXLogFileSegment(endlogSegNo, path,
4254-
true, recycleSegNo, true))
4236+
true, recycleSegNo))
42554237
{
42564238
ereport(DEBUG2,
42574239
(errmsg_internal("recycled write-ahead log file \"%s\"",
@@ -5388,7 +5370,7 @@ BootStrapXLOG(void)
53885370

53895371
/* Create first XLOG segment file */
53905372
use_existent = false;
5391-
openLogFile = XLogFileInit(1, &use_existent, false);
5373+
openLogFile = XLogFileInit(1, &use_existent);
53925374

53935375
/*
53945376
* We needn't bother with Reserve/ReleaseExternalFD here, since we'll
@@ -5697,7 +5679,7 @@ exitArchiveRecovery(TimeLineID endTLI, XLogRecPtr endOfLog)
56975679
bool use_existent = true;
56985680
int fd;
56995681

5700-
fd = XLogFileInit(startLogSegNo, &use_existent, true);
5682+
fd = XLogFileInit(startLogSegNo, &use_existent);
57015683

57025684
if (close(fd) != 0)
57035685
{

src/backend/replication/walreceiver.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -894,7 +894,7 @@ XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr)
894894

895895
/* Create/use new log file */
896896
XLByteToSeg(recptr, recvSegNo, wal_segment_size);
897-
recvFile = XLogFileInit(recvSegNo, &use_existent, true);
897+
recvFile = XLogFileInit(recvSegNo, &use_existent);
898898
recvFileTLI = ThisTimeLineID;
899899
}
900900

src/include/access/xlog.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ extern XLogRecPtr XLogInsertRecord(struct XLogRecData *rdata,
296296
extern void XLogFlush(XLogRecPtr RecPtr);
297297
extern bool XLogBackgroundFlush(void);
298298
extern bool XLogNeedsFlush(XLogRecPtr RecPtr);
299-
extern int XLogFileInit(XLogSegNo segno, bool *use_existent, bool use_lock);
299+
extern int XLogFileInit(XLogSegNo segno, bool *use_existent);
300300
extern int XLogFileOpen(XLogSegNo segno);
301301

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

0 commit comments

Comments
 (0)