Author: Noah Misch Commit: Noah Misch 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. Discussion: https://postgr.es/m/20210202151416.GB3304930@rfd.leadboat.com diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 073dabc..1a31788 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -2424,7 +2424,7 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible) bool ispartialpage; bool last_iteration; bool finishing_seg; - bool use_existent; + bool added; int curridx; int npages; int startidx; @@ -2490,8 +2490,7 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible) wal_segment_size); /* create/use new log file */ - use_existent = true; - openLogFile = XLogFileInit(openLogSegNo, &use_existent); + openLogFile = XLogFileInit(openLogSegNo, &added); ReserveExternalFD(); } @@ -3260,9 +3259,7 @@ XLogNeedsFlush(XLogRecPtr record) * * logsegno: identify segment to be created/opened. * - * *use_existent: if true, OK to use a pre-existing file (else, any - * pre-existing file will be deleted). On return, false iff this call added - * some segment on disk. + * *added: on return, true if this call raised the number of extant segments. * * Returns FD of opened file. * @@ -3272,7 +3269,7 @@ XLogNeedsFlush(XLogRecPtr record) * in a critical section. */ int -XLogFileInit(XLogSegNo logsegno, bool *use_existent) +XLogFileInit(XLogSegNo logsegno, bool *added) { char path[MAXPGPATH]; char tmppath[MAXPGPATH]; @@ -3287,19 +3284,17 @@ XLogFileInit(XLogSegNo logsegno, bool *use_existent) /* * Try to use existent file (checkpoint maker may have created it already) */ - if (*use_existent) + *added = false; + fd = BasicOpenFile(path, O_RDWR | PG_BINARY | get_sync_bit(sync_method)); + if (fd < 0) { - fd = BasicOpenFile(path, O_RDWR | PG_BINARY | get_sync_bit(sync_method)); - if (fd < 0) - { - if (errno != ENOENT) - ereport(ERROR, - (errcode_for_file_access(), - errmsg("could not open file \"%s\": %m", path))); - } - else - return fd; + if (errno != ENOENT) + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not open file \"%s\": %m", path))); } + else + return fd; /* * Initialize an empty (all zeroes) segment. NOTE: it is possible that @@ -3412,12 +3407,9 @@ XLogFileInit(XLogSegNo logsegno, bool *use_existent) errmsg("could not close file \"%s\": %m", tmppath))); /* - * Now move the segment into place with its final name. - * - * If caller didn't want to use a pre-existing file, get rid of any - * pre-existing file. Otherwise, cope with possibility that someone else - * has created the file while we were filling ours: if so, use ours to - * pre-create a future log segment. + * Now move the segment into place with its final name. Cope with + * possibility that someone else has created the file while we were + * filling ours: if so, use ours to pre-create a future log segment. */ installed_segno = logsegno; @@ -3431,9 +3423,8 @@ XLogFileInit(XLogSegNo logsegno, bool *use_existent) * CheckPointSegments. */ max_segno = logsegno + CheckPointSegments; - if (InstallXLogFileSegment(&installed_segno, tmppath, - *use_existent, max_segno)) - *use_existent = false; + if (InstallXLogFileSegment(&installed_segno, tmppath, true, max_segno)) + *added = true; else { /* @@ -3918,7 +3909,7 @@ PreallocXlogFiles(XLogRecPtr endptr) { XLogSegNo _logSegNo; int lf; - bool use_existent; + bool added; uint64 offset; XLByteToPrevSeg(endptr, _logSegNo, wal_segment_size); @@ -3926,10 +3917,9 @@ PreallocXlogFiles(XLogRecPtr endptr) if (offset >= (uint32) (0.75 * wal_segment_size)) { _logSegNo++; - use_existent = true; - lf = XLogFileInit(_logSegNo, &use_existent); + lf = XLogFileInit(_logSegNo, &added); close(lf); - if (!use_existent) + if (added) CheckpointStats.ckpt_segs_added++; } } @@ -5224,7 +5214,7 @@ BootStrapXLOG(void) XLogLongPageHeader longpage; XLogRecord *record; char *recptr; - bool use_existent; + bool added; uint64 sysidentifier; struct timeval tv; pg_crc32c crc; @@ -5321,8 +5311,7 @@ BootStrapXLOG(void) record->xl_crc = crc; /* Create first XLOG segment file */ - use_existent = false; - openLogFile = XLogFileInit(1, &use_existent); + openLogFile = XLogFileInit(1, &added); /* * We needn't bother with Reserve/ReleaseExternalFD here, since we'll @@ -5628,10 +5617,10 @@ exitArchiveRecovery(TimeLineID endTLI, XLogRecPtr endOfLog) * The switch happened at a segment boundary, so just create the next * segment on the new timeline. */ - bool use_existent = true; + bool added; int fd; - fd = XLogFileInit(startLogSegNo, &use_existent); + fd = XLogFileInit(startLogSegNo, &added); if (close(fd) != 0) { diff --git a/src/backend/replication/walreceiver.c b/src/backend/replication/walreceiver.c index b00066e..eadff8f 100644 --- a/src/backend/replication/walreceiver.c +++ b/src/backend/replication/walreceiver.c @@ -885,7 +885,7 @@ XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr) if (recvFile < 0 || !XLByteInSeg(recptr, recvSegNo, wal_segment_size)) { - bool use_existent; + bool added; /* * fsync() and close current file before we switch to next one. We @@ -923,8 +923,7 @@ XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr) /* Create/use new log file */ XLByteToSeg(recptr, recvSegNo, wal_segment_size); - use_existent = true; - recvFile = XLogFileInit(recvSegNo, &use_existent); + recvFile = XLogFileInit(recvSegNo, &added); recvFileTLI = ThisTimeLineID; } diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h index a175649..d8b8f59 100644 --- a/src/include/access/xlog.h +++ b/src/include/access/xlog.h @@ -296,7 +296,7 @@ extern XLogRecPtr XLogInsertRecord(struct XLogRecData *rdata, extern void XLogFlush(XLogRecPtr RecPtr); extern bool XLogBackgroundFlush(void); extern bool XLogNeedsFlush(XLogRecPtr RecPtr); -extern int XLogFileInit(XLogSegNo segno, bool *use_existent); +extern int XLogFileInit(XLogSegNo segno, bool *added); extern int XLogFileOpen(XLogSegNo segno); extern void CheckXLogRemoved(XLogSegNo segno, TimeLineID tli);