Remove XLogFileInit() ability to skip ControlFileLock.

Cold paths, initdb and end-of-recovery, used it.  Don't optimize them.

Discussion: https://postgr.es/m/20210202151416.GB3304930@rfd.leadboat.com
This commit is contained in:
Noah Misch 2021-06-28 18:34:55 -07:00
parent 7ac10f6920
commit c53c6b98d3
3 changed files with 16 additions and 34 deletions

View File

@ -913,8 +913,7 @@ static void AdvanceXLInsertBuffer(XLogRecPtr upto, bool opportunistic);
static bool XLogCheckpointNeeded(XLogSegNo new_segno); static bool XLogCheckpointNeeded(XLogSegNo new_segno);
static void XLogWrite(XLogwrtRqst WriteRqst, bool flexible); static void XLogWrite(XLogwrtRqst WriteRqst, bool flexible);
static bool InstallXLogFileSegment(XLogSegNo *segno, char *tmppath, static bool InstallXLogFileSegment(XLogSegNo *segno, char *tmppath,
bool find_free, XLogSegNo max_segno, bool find_free, XLogSegNo max_segno);
bool use_lock);
static int XLogFileRead(XLogSegNo segno, int emode, TimeLineID tli, static int XLogFileRead(XLogSegNo segno, int emode, TimeLineID tli,
XLogSource source, bool notfoundOk); XLogSource source, bool notfoundOk);
static int XLogFileReadAnyTLI(XLogSegNo segno, int emode, XLogSource source); static int XLogFileReadAnyTLI(XLogSegNo segno, int emode, XLogSource source);
@ -2492,7 +2491,7 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
/* create/use new log file */ /* create/use new log file */
use_existent = true; use_existent = true;
openLogFile = XLogFileInit(openLogSegNo, &use_existent, true); openLogFile = XLogFileInit(openLogSegNo, &use_existent);
ReserveExternalFD(); ReserveExternalFD();
} }
@ -3265,10 +3264,6 @@ XLogNeedsFlush(XLogRecPtr record)
* pre-existing file will be deleted). On return, true if a pre-existing * pre-existing file will be deleted). On return, true if a pre-existing
* file was used. * file was used.
* *
* use_lock: if true, acquire ControlFileLock while moving file into
* place. This should be true except during bootstrap log creation. The
* caller must *not* hold the lock at call.
*
* Returns FD of opened file. * Returns FD of opened file.
* *
* Note: errors here are ERROR not PANIC because we might or might not be * Note: errors here are ERROR not PANIC because we might or might not be
@ -3277,7 +3272,7 @@ XLogNeedsFlush(XLogRecPtr record)
* in a critical section. * in a critical section.
*/ */
int int
XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock) XLogFileInit(XLogSegNo logsegno, bool *use_existent)
{ {
char path[MAXPGPATH]; char path[MAXPGPATH];
char tmppath[MAXPGPATH]; char tmppath[MAXPGPATH];
@ -3437,8 +3432,7 @@ XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock)
*/ */
max_segno = logsegno + CheckPointSegments; max_segno = logsegno + CheckPointSegments;
if (!InstallXLogFileSegment(&installed_segno, tmppath, if (!InstallXLogFileSegment(&installed_segno, tmppath,
*use_existent, max_segno, *use_existent, max_segno))
use_lock))
{ {
/* /*
* No need for any more future segments, or InstallXLogFileSegment() * No need for any more future segments, or InstallXLogFileSegment()
@ -3592,7 +3586,7 @@ XLogFileCopy(XLogSegNo destsegno, TimeLineID srcTLI, XLogSegNo srcsegno,
/* /*
* Now move the segment into place with its final name. * Now move the segment into place with its final name.
*/ */
if (!InstallXLogFileSegment(&destsegno, tmppath, false, 0, false)) if (!InstallXLogFileSegment(&destsegno, tmppath, false, 0))
elog(ERROR, "InstallXLogFileSegment should not have failed"); elog(ERROR, "InstallXLogFileSegment should not have failed");
} }
@ -3616,29 +3610,20 @@ XLogFileCopy(XLogSegNo destsegno, TimeLineID srcTLI, XLogSegNo srcsegno,
* free slot is found between *segno and max_segno. (Ignored when find_free * free slot is found between *segno and max_segno. (Ignored when find_free
* is false.) * is false.)
* *
* use_lock: if true, acquire ControlFileLock while moving file into
* place. This should be true except during bootstrap log creation. The
* caller must *not* hold the lock at call.
*
* Returns true if the file was installed successfully. false indicates that * Returns true if the file was installed successfully. false indicates that
* max_segno limit was exceeded, or an error occurred while renaming the * max_segno limit was exceeded, or an error occurred while renaming the
* file into place. * file into place.
*/ */
static bool static bool
InstallXLogFileSegment(XLogSegNo *segno, char *tmppath, InstallXLogFileSegment(XLogSegNo *segno, char *tmppath,
bool find_free, XLogSegNo max_segno, bool find_free, XLogSegNo max_segno)
bool use_lock)
{ {
char path[MAXPGPATH]; char path[MAXPGPATH];
struct stat stat_buf; struct stat stat_buf;
XLogFilePath(path, ThisTimeLineID, *segno, wal_segment_size); XLogFilePath(path, ThisTimeLineID, *segno, wal_segment_size);
/* LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
* We want to be sure that only one process does this at a time.
*/
if (use_lock)
LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
if (!find_free) if (!find_free)
{ {
@ -3653,8 +3638,7 @@ InstallXLogFileSegment(XLogSegNo *segno, char *tmppath,
if ((*segno) >= max_segno) if ((*segno) >= max_segno)
{ {
/* Failed to find a free slot within specified range */ /* Failed to find a free slot within specified range */
if (use_lock) LWLockRelease(ControlFileLock);
LWLockRelease(ControlFileLock);
return false; return false;
} }
(*segno)++; (*segno)++;
@ -3668,14 +3652,12 @@ InstallXLogFileSegment(XLogSegNo *segno, char *tmppath,
*/ */
if (durable_rename_excl(tmppath, path, LOG) != 0) if (durable_rename_excl(tmppath, path, LOG) != 0)
{ {
if (use_lock) LWLockRelease(ControlFileLock);
LWLockRelease(ControlFileLock);
/* durable_rename_excl already emitted log message */ /* durable_rename_excl already emitted log message */
return false; return false;
} }
if (use_lock) LWLockRelease(ControlFileLock);
LWLockRelease(ControlFileLock);
return true; return true;
} }
@ -3946,7 +3928,7 @@ PreallocXlogFiles(XLogRecPtr endptr)
{ {
_logSegNo++; _logSegNo++;
use_existent = true; use_existent = true;
lf = XLogFileInit(_logSegNo, &use_existent, true); lf = XLogFileInit(_logSegNo, &use_existent);
close(lf); close(lf);
if (!use_existent) if (!use_existent)
CheckpointStats.ckpt_segs_added++; CheckpointStats.ckpt_segs_added++;
@ -4223,7 +4205,7 @@ RemoveXlogFile(const char *segname, XLogSegNo recycleSegNo,
*endlogSegNo <= recycleSegNo && *endlogSegNo <= recycleSegNo &&
lstat(path, &statbuf) == 0 && S_ISREG(statbuf.st_mode) && lstat(path, &statbuf) == 0 && S_ISREG(statbuf.st_mode) &&
InstallXLogFileSegment(endlogSegNo, path, InstallXLogFileSegment(endlogSegNo, path,
true, recycleSegNo, true)) true, recycleSegNo))
{ {
ereport(DEBUG2, ereport(DEBUG2,
(errmsg_internal("recycled write-ahead log file \"%s\"", (errmsg_internal("recycled write-ahead log file \"%s\"",
@ -5341,7 +5323,7 @@ BootStrapXLOG(void)
/* Create first XLOG segment file */ /* Create first XLOG segment file */
use_existent = false; use_existent = false;
openLogFile = XLogFileInit(1, &use_existent, false); openLogFile = XLogFileInit(1, &use_existent);
/* /*
* We needn't bother with Reserve/ReleaseExternalFD here, since we'll * We needn't bother with Reserve/ReleaseExternalFD here, since we'll
@ -5650,7 +5632,7 @@ exitArchiveRecovery(TimeLineID endTLI, XLogRecPtr endOfLog)
bool use_existent = true; bool use_existent = true;
int fd; int fd;
fd = XLogFileInit(startLogSegNo, &use_existent, true); fd = XLogFileInit(startLogSegNo, &use_existent);
if (close(fd) != 0) if (close(fd) != 0)
{ {

View File

@ -924,7 +924,7 @@ XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr)
/* Create/use new log file */ /* Create/use new log file */
XLByteToSeg(recptr, recvSegNo, wal_segment_size); XLByteToSeg(recptr, recvSegNo, wal_segment_size);
use_existent = true; use_existent = true;
recvFile = XLogFileInit(recvSegNo, &use_existent, true); recvFile = XLogFileInit(recvSegNo, &use_existent);
recvFileTLI = ThisTimeLineID; recvFileTLI = ThisTimeLineID;
} }

View File

@ -296,7 +296,7 @@ extern XLogRecPtr XLogInsertRecord(struct XLogRecData *rdata,
extern void XLogFlush(XLogRecPtr RecPtr); extern void XLogFlush(XLogRecPtr RecPtr);
extern bool XLogBackgroundFlush(void); extern bool XLogBackgroundFlush(void);
extern bool XLogNeedsFlush(XLogRecPtr RecPtr); extern bool XLogNeedsFlush(XLogRecPtr RecPtr);
extern int XLogFileInit(XLogSegNo segno, bool *use_existent, bool use_lock); extern int XLogFileInit(XLogSegNo segno, bool *use_existent);
extern int XLogFileOpen(XLogSegNo segno); extern int XLogFileOpen(XLogSegNo segno);
extern void CheckXLogRemoved(XLogSegNo segno, TimeLineID tli); extern void CheckXLogRemoved(XLogSegNo segno, TimeLineID tli);