]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Remove XLogFileInit() ability to unlink a pre-existing file.
authorNoah Misch <noah@leadboat.com>
Tue, 29 Jun 2021 01:34:56 +0000 (18:34 -0700)
committerMichael Paquier <michael@paquier.xyz>
Sun, 6 Apr 2025 05:46:31 +0000 (14:46 +0900)
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 421484f79c0b 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 1f95181b44c8, 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

src/backend/access/transam/xlog.c
src/backend/replication/walreceiver.c
src/include/access/xlog.h

index c9176eea68c4dcc5871b29191da125b0c0ce3c98..d862954709088b93e6f921a14176f562c4d92a1d 100644 (file)
@@ -2452,7 +2452,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;
@@ -2518,8 +2518,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();
                }
 
@@ -3288,9 +3287,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.
  *
@@ -3300,7 +3297,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];
@@ -3315,19 +3312,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
@@ -3440,12 +3435,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;
 
@@ -3459,9 +3451,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
        {
                /*
@@ -3946,7 +3937,7 @@ PreallocXlogFiles(XLogRecPtr endptr)
 {
        XLogSegNo       _logSegNo;
        int                     lf;
-       bool            use_existent;
+       bool            added;
        uint64          offset;
 
        XLByteToPrevSeg(endptr, _logSegNo, wal_segment_size);
@@ -3954,10 +3945,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++;
        }
 }
@@ -5271,7 +5261,7 @@ BootStrapXLOG(void)
        XLogLongPageHeader longpage;
        XLogRecord *record;
        char       *recptr;
-       bool            use_existent;
+       bool            added;
        uint64          sysidentifier;
        struct timeval tv;
        pg_crc32c       crc;
@@ -5368,8 +5358,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
@@ -5675,10 +5664,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)
                {
index 4ad20f12b61be8fd0cb12962b5ed6a36500a8aee..b6f07ab81f1d6c3a857cbea4e723a6b95bbf3d83 100644 (file)
@@ -890,11 +890,11 @@ XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr)
 
                if (recvFile < 0)
                {
-                       bool            use_existent = true;
+                       bool            added = true;
 
                        /* Create/use new log file */
                        XLByteToSeg(recptr, recvSegNo, wal_segment_size);
-                       recvFile = XLogFileInit(recvSegNo, &use_existent);
+                       recvFile = XLogFileInit(recvSegNo, &added);
                        recvFileTLI = ThisTimeLineID;
                }
 
index 596965d353d03f6167f682de4345ebccdae00d00..1860107f9a2e5db4708ac7995b818fb56800e228 100644 (file)
@@ -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);