At Tue, 3 Sep 2024 12:02:26 +0300, "Anton A. Melnikov" 
<a.melni...@postgrespro.ru> wrote in 
> In v2 removed XLOG_CONTROL_FILE from args and used it directly in the
> string.
> IMHO this makes the code more readable and will output the correct
> text if the macro changes.

Yeah, I had this in my mind. Looks good to me.

> 3)
..
> Maybe include/access/xlogdefs.h would be a good place for this?
> In v2 moved some definitions from xlog_internal to xlogdefs
> and removed including xlog_internal.h from the postmaster.c.
> Please, take a look on it.

The change can help avoid disrupting existing users of the
macro. However, the file is documented as follows:

>  * Postgres write-ahead log manager record pointer and
>  * timeline number definitions

We could modify the file definition, but I'm not sure if that's the
best approach. Instead, I'd like to propose separating the file and
path-related definitions from xlog_internal.h, as shown in the
attached first patch. This change would allow some modules to include
files without unnecessary details.

The second file is your patch, adjusted based on the first patch.

I’d appreciate hearing from others on whether they find the first
patch worthwhile. If it’s not considered worthwhile, then I believe
having postmaster include xlog_internal.h would be the best approach.

regards.

-- 
Kyotaro Horiguchi
NTT Open Source Software Center
>From 22b71830ff601717d01dc66be95bafb930b1a0ea Mon Sep 17 00:00:00 2001
From: Kyotaro Horiguchi <horikyota....@gmail.com>
Date: Wed, 4 Sep 2024 16:15:16 +0900
Subject: [PATCH 1/2] Split file-related parts from xlog_internal.h

Some modules that require XLOG file manipulation had to include
xlog_internal.h, which contains excessively detailed internal
information. This commit separates the file and file path-related
components into xlogfilepaths.h, thereby avoiding the exposure of
unrelated details of the XLOG module.
---
 src/backend/access/transam/timeline.c         |   1 -
 src/backend/postmaster/pgarch.c               |   1 -
 src/backend/utils/adt/genfile.c               |   1 -
 src/bin/initdb/initdb.c                       |   1 +
 src/bin/pg_archivecleanup/pg_archivecleanup.c |   2 +-
 src/bin/pg_basebackup/pg_basebackup.c         |   4 +-
 src/bin/pg_basebackup/pg_receivewal.c         |   1 +
 src/bin/pg_basebackup/pg_recvlogical.c        |   1 -
 src/bin/pg_basebackup/receivelog.c            |   2 +-
 src/bin/pg_basebackup/streamutil.c            |   2 +-
 src/bin/pg_controldata/pg_controldata.c       |   1 -
 src/bin/pg_rewind/pg_rewind.c                 |   2 +-
 src/include/access/xlog.h                     |  13 +-
 src/include/access/xlog_internal.h            | 178 +-------------
 src/include/access/xlogfilepaths.h            | 219 ++++++++++++++++++
 15 files changed, 230 insertions(+), 199 deletions(-)
 create mode 100644 src/include/access/xlogfilepaths.h

diff --git a/src/backend/access/transam/timeline.c b/src/backend/access/transam/timeline.c
index 146751ae37..18df8fd326 100644
--- a/src/backend/access/transam/timeline.c
+++ b/src/backend/access/transam/timeline.c
@@ -38,7 +38,6 @@
 #include "access/xlog.h"
 #include "access/xlog_internal.h"
 #include "access/xlogarchive.h"
-#include "access/xlogdefs.h"
 #include "pgstat.h"
 #include "storage/fd.h"
 
diff --git a/src/backend/postmaster/pgarch.c b/src/backend/postmaster/pgarch.c
index 02f91431f5..4971cd76ff 100644
--- a/src/backend/postmaster/pgarch.c
+++ b/src/backend/postmaster/pgarch.c
@@ -30,7 +30,6 @@
 #include <unistd.h>
 
 #include "access/xlog.h"
-#include "access/xlog_internal.h"
 #include "archive/archive_module.h"
 #include "archive/shell_archive.h"
 #include "lib/binaryheap.h"
diff --git a/src/backend/utils/adt/genfile.c b/src/backend/utils/adt/genfile.c
index 24b95c32b7..17be1756e2 100644
--- a/src/backend/utils/adt/genfile.c
+++ b/src/backend/utils/adt/genfile.c
@@ -21,7 +21,6 @@
 #include <dirent.h>
 
 #include "access/htup_details.h"
-#include "access/xlog_internal.h"
 #include "catalog/pg_authid.h"
 #include "catalog/pg_tablespace_d.h"
 #include "catalog/pg_type.h"
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index f00718a015..95ec8d9c92 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -65,6 +65,7 @@
 #endif
 
 #include "access/xlog_internal.h"
+#include "lib/stringinfo.h"
 #include "catalog/pg_authid_d.h"
 #include "catalog/pg_class_d.h" /* pgrminclude ignore */
 #include "catalog/pg_collation_d.h"
diff --git a/src/bin/pg_archivecleanup/pg_archivecleanup.c b/src/bin/pg_archivecleanup/pg_archivecleanup.c
index 5a124385b7..f6b33de32a 100644
--- a/src/bin/pg_archivecleanup/pg_archivecleanup.c
+++ b/src/bin/pg_archivecleanup/pg_archivecleanup.c
@@ -15,7 +15,7 @@
 #include <signal.h>
 #include <sys/time.h>
 
-#include "access/xlog_internal.h"
+#include "access/xlogfilepaths.h"
 #include "common/logging.h"
 #include "getopt_long.h"
 
diff --git a/src/bin/pg_basebackup/pg_basebackup.c b/src/bin/pg_basebackup/pg_basebackup.c
index e41a6cfbda..f86af782dc 100644
--- a/src/bin/pg_basebackup/pg_basebackup.c
+++ b/src/bin/pg_basebackup/pg_basebackup.c
@@ -25,7 +25,7 @@
 #include <zlib.h>
 #endif
 
-#include "access/xlog_internal.h"
+#include "access/xlogfilepaths.h"
 #include "astreamer_inject.h"
 #include "backup/basebackup.h"
 #include "common/compression.h"
@@ -35,6 +35,8 @@
 #include "fe_utils/option_utils.h"
 #include "fe_utils/recovery_gen.h"
 #include "getopt_long.h"
+#include "pgtime.h"
+#include "port/pg_bswap.h"
 #include "receivelog.h"
 #include "streamutil.h"
 
diff --git a/src/bin/pg_basebackup/pg_receivewal.c b/src/bin/pg_basebackup/pg_receivewal.c
index 555f0175f0..dbbbeabbc4 100644
--- a/src/bin/pg_basebackup/pg_receivewal.c
+++ b/src/bin/pg_basebackup/pg_receivewal.c
@@ -27,6 +27,7 @@
 #include <zlib.h>
 #endif
 
+//#include "access/xlogfilepaths.h"
 #include "access/xlog_internal.h"
 #include "common/file_perm.h"
 #include "common/logging.h"
diff --git a/src/bin/pg_basebackup/pg_recvlogical.c b/src/bin/pg_basebackup/pg_recvlogical.c
index 3db520ed38..f242f1f379 100644
--- a/src/bin/pg_basebackup/pg_recvlogical.c
+++ b/src/bin/pg_basebackup/pg_recvlogical.c
@@ -18,7 +18,6 @@
 #include <sys/stat.h>
 #include <unistd.h>
 
-#include "access/xlog_internal.h"
 #include "common/fe_memutils.h"
 #include "common/file_perm.h"
 #include "common/logging.h"
diff --git a/src/bin/pg_basebackup/receivelog.c b/src/bin/pg_basebackup/receivelog.c
index 70f4246764..6db16df4bc 100644
--- a/src/bin/pg_basebackup/receivelog.c
+++ b/src/bin/pg_basebackup/receivelog.c
@@ -18,7 +18,7 @@
 #include <sys/stat.h>
 #include <unistd.h>
 
-#include "access/xlog_internal.h"
+#include "access/xlogfilepaths.h"
 #include "common/file_utils.h"
 #include "common/logging.h"
 #include "libpq-fe.h"
diff --git a/src/bin/pg_basebackup/streamutil.c b/src/bin/pg_basebackup/streamutil.c
index 30b3d9a377..e65c5eb060 100644
--- a/src/bin/pg_basebackup/streamutil.c
+++ b/src/bin/pg_basebackup/streamutil.c
@@ -17,7 +17,7 @@
 #include <sys/time.h>
 #include <unistd.h>
 
-#include "access/xlog_internal.h"
+#include "access/xlogfilepaths.h"
 #include "common/connect.h"
 #include "common/fe_memutils.h"
 #include "common/file_perm.h"
diff --git a/src/bin/pg_controldata/pg_controldata.c b/src/bin/pg_controldata/pg_controldata.c
index 93a05d80ca..233230712a 100644
--- a/src/bin/pg_controldata/pg_controldata.c
+++ b/src/bin/pg_controldata/pg_controldata.c
@@ -22,7 +22,6 @@
 
 #include "access/transam.h"
 #include "access/xlog.h"
-#include "access/xlog_internal.h"
 #include "catalog/pg_control.h"
 #include "common/controldata_utils.h"
 #include "common/logging.h"
diff --git a/src/bin/pg_rewind/pg_rewind.c b/src/bin/pg_rewind/pg_rewind.c
index 1027d235dc..c4b97abd03 100644
--- a/src/bin/pg_rewind/pg_rewind.c
+++ b/src/bin/pg_rewind/pg_rewind.c
@@ -15,7 +15,7 @@
 #include <unistd.h>
 
 #include "access/timeline.h"
-#include "access/xlog_internal.h"
+#include "access/xlogfilepaths.h"
 #include "catalog/catversion.h"
 #include "catalog/pg_control.h"
 #include "common/controldata_utils.h"
diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h
index 083810f5b4..09655c2c34 100644
--- a/src/include/access/xlog.h
+++ b/src/include/access/xlog.h
@@ -16,6 +16,7 @@
 #include "datatype/timestamp.h"
 #include "lib/stringinfo.h"
 #include "nodes/pg_list.h"
+#include "access/xlogfilepaths.h"
 
 
 /* Sync methods */
@@ -297,16 +298,4 @@ extern void do_pg_abort_backup(int code, Datum arg);
 extern void register_persistent_abort_backup_handler(void);
 extern SessionBackupState get_backup_status(void);
 
-/* File path names (all relative to $PGDATA) */
-#define RECOVERY_SIGNAL_FILE	"recovery.signal"
-#define STANDBY_SIGNAL_FILE		"standby.signal"
-#define BACKUP_LABEL_FILE		"backup_label"
-#define BACKUP_LABEL_OLD		"backup_label.old"
-
-#define TABLESPACE_MAP			"tablespace_map"
-#define TABLESPACE_MAP_OLD		"tablespace_map.old"
-
-/* files to signal promotion to primary */
-#define PROMOTE_SIGNAL_FILE		"promote"
-
 #endif							/* XLOG_H */
diff --git a/src/include/access/xlog_internal.h b/src/include/access/xlog_internal.h
index e5cdba0584..39e52cec47 100644
--- a/src/include/access/xlog_internal.h
+++ b/src/include/access/xlog_internal.h
@@ -21,6 +21,7 @@
 
 #include "access/xlogdefs.h"
 #include "access/xlogreader.h"
+#include "access/xlogfilepaths.h"
 #include "datatype/timestamp.h"
 #include "lib/stringinfo.h"
 #include "pgtime.h"
@@ -84,187 +85,10 @@ typedef XLogLongPageHeaderData *XLogLongPageHeader;
 #define XLogPageHeaderSize(hdr)		\
 	(((hdr)->xlp_info & XLP_LONG_HEADER) ? SizeOfXLogLongPHD : SizeOfXLogShortPHD)
 
-/* wal_segment_size can range from 1MB to 1GB */
-#define WalSegMinSize 1024 * 1024
-#define WalSegMaxSize 1024 * 1024 * 1024
-/* default number of min and max wal segments */
-#define DEFAULT_MIN_WAL_SEGS 5
-#define DEFAULT_MAX_WAL_SEGS 64
-
-/* check that the given size is a valid wal_segment_size */
-#define IsPowerOf2(x) (x > 0 && ((x) & ((x)-1)) == 0)
-#define IsValidWalSegSize(size) \
-	 (IsPowerOf2(size) && \
-	 ((size) >= WalSegMinSize && (size) <= WalSegMaxSize))
-
-#define XLogSegmentsPerXLogId(wal_segsz_bytes)	\
-	(UINT64CONST(0x100000000) / (wal_segsz_bytes))
-
-#define XLogSegNoOffsetToRecPtr(segno, offset, wal_segsz_bytes, dest) \
-		(dest) = (segno) * (wal_segsz_bytes) + (offset)
-
-#define XLogSegmentOffset(xlogptr, wal_segsz_bytes)	\
-	((xlogptr) & ((wal_segsz_bytes) - 1))
-
-/*
- * Compute a segment number from an XLogRecPtr.
- *
- * For XLByteToSeg, do the computation at face value.  For XLByteToPrevSeg,
- * a boundary byte is taken to be in the previous segment.  This is suitable
- * for deciding which segment to write given a pointer to a record end,
- * for example.
- */
-#define XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes) \
-	logSegNo = (xlrp) / (wal_segsz_bytes)
-
-#define XLByteToPrevSeg(xlrp, logSegNo, wal_segsz_bytes) \
-	logSegNo = ((xlrp) - 1) / (wal_segsz_bytes)
-
-/*
- * Convert values of GUCs measured in megabytes to equiv. segment count.
- * Rounds down.
- */
-#define XLogMBVarToSegs(mbvar, wal_segsz_bytes) \
-	((mbvar) / ((wal_segsz_bytes) / (1024 * 1024)))
-
-/*
- * Is an XLogRecPtr within a particular XLOG segment?
- *
- * For XLByteInSeg, do the computation at face value.  For XLByteInPrevSeg,
- * a boundary byte is taken to be in the previous segment.
- */
-#define XLByteInSeg(xlrp, logSegNo, wal_segsz_bytes) \
-	(((xlrp) / (wal_segsz_bytes)) == (logSegNo))
-
-#define XLByteInPrevSeg(xlrp, logSegNo, wal_segsz_bytes) \
-	((((xlrp) - 1) / (wal_segsz_bytes)) == (logSegNo))
-
 /* Check if an XLogRecPtr value is in a plausible range */
 #define XRecOffIsValid(xlrp) \
 		((xlrp) % XLOG_BLCKSZ >= SizeOfXLogShortPHD)
 
-/*
- * The XLog directory and control file (relative to $PGDATA)
- */
-#define XLOGDIR				"pg_wal"
-#define XLOG_CONTROL_FILE	"global/pg_control"
-
-/*
- * These macros encapsulate knowledge about the exact layout of XLog file
- * names, timeline history file names, and archive-status file names.
- */
-#define MAXFNAMELEN		64
-
-/* Length of XLog file name */
-#define XLOG_FNAME_LEN	   24
-
-/*
- * Generate a WAL segment file name.  Do not use this function in a helper
- * function allocating the result generated.
- */
-static inline void
-XLogFileName(char *fname, TimeLineID tli, XLogSegNo logSegNo, int wal_segsz_bytes)
-{
-	snprintf(fname, MAXFNAMELEN, "%08X%08X%08X", tli,
-			 (uint32) (logSegNo / XLogSegmentsPerXLogId(wal_segsz_bytes)),
-			 (uint32) (logSegNo % XLogSegmentsPerXLogId(wal_segsz_bytes)));
-}
-
-static inline void
-XLogFileNameById(char *fname, TimeLineID tli, uint32 log, uint32 seg)
-{
-	snprintf(fname, MAXFNAMELEN, "%08X%08X%08X", tli, log, seg);
-}
-
-static inline bool
-IsXLogFileName(const char *fname)
-{
-	return (strlen(fname) == XLOG_FNAME_LEN && \
-			strspn(fname, "0123456789ABCDEF") == XLOG_FNAME_LEN);
-}
-
-/*
- * XLOG segment with .partial suffix.  Used by pg_receivewal and at end of
- * archive recovery, when we want to archive a WAL segment but it might not
- * be complete yet.
- */
-static inline bool
-IsPartialXLogFileName(const char *fname)
-{
-	return (strlen(fname) == XLOG_FNAME_LEN + strlen(".partial") &&
-			strspn(fname, "0123456789ABCDEF") == XLOG_FNAME_LEN &&
-			strcmp(fname + XLOG_FNAME_LEN, ".partial") == 0);
-}
-
-static inline void
-XLogFromFileName(const char *fname, TimeLineID *tli, XLogSegNo *logSegNo, int wal_segsz_bytes)
-{
-	uint32		log;
-	uint32		seg;
-
-	sscanf(fname, "%08X%08X%08X", tli, &log, &seg);
-	*logSegNo = (uint64) log * XLogSegmentsPerXLogId(wal_segsz_bytes) + seg;
-}
-
-static inline void
-XLogFilePath(char *path, TimeLineID tli, XLogSegNo logSegNo, int wal_segsz_bytes)
-{
-	snprintf(path, MAXPGPATH, XLOGDIR "/%08X%08X%08X", tli,
-			 (uint32) (logSegNo / XLogSegmentsPerXLogId(wal_segsz_bytes)),
-			 (uint32) (logSegNo % XLogSegmentsPerXLogId(wal_segsz_bytes)));
-}
-
-static inline void
-TLHistoryFileName(char *fname, TimeLineID tli)
-{
-	snprintf(fname, MAXFNAMELEN, "%08X.history", tli);
-}
-
-static inline bool
-IsTLHistoryFileName(const char *fname)
-{
-	return (strlen(fname) == 8 + strlen(".history") &&
-			strspn(fname, "0123456789ABCDEF") == 8 &&
-			strcmp(fname + 8, ".history") == 0);
-}
-
-static inline void
-TLHistoryFilePath(char *path, TimeLineID tli)
-{
-	snprintf(path, MAXPGPATH, XLOGDIR "/%08X.history", tli);
-}
-
-static inline void
-StatusFilePath(char *path, const char *xlog, const char *suffix)
-{
-	snprintf(path, MAXPGPATH, XLOGDIR "/archive_status/%s%s", xlog, suffix);
-}
-
-static inline void
-BackupHistoryFileName(char *fname, TimeLineID tli, XLogSegNo logSegNo, XLogRecPtr startpoint, int wal_segsz_bytes)
-{
-	snprintf(fname, MAXFNAMELEN, "%08X%08X%08X.%08X.backup", tli,
-			 (uint32) (logSegNo / XLogSegmentsPerXLogId(wal_segsz_bytes)),
-			 (uint32) (logSegNo % XLogSegmentsPerXLogId(wal_segsz_bytes)),
-			 (uint32) (XLogSegmentOffset(startpoint, wal_segsz_bytes)));
-}
-
-static inline bool
-IsBackupHistoryFileName(const char *fname)
-{
-	return (strlen(fname) > XLOG_FNAME_LEN &&
-			strspn(fname, "0123456789ABCDEF") == XLOG_FNAME_LEN &&
-			strcmp(fname + strlen(fname) - strlen(".backup"), ".backup") == 0);
-}
-
-static inline void
-BackupHistoryFilePath(char *path, TimeLineID tli, XLogSegNo logSegNo, XLogRecPtr startpoint, int wal_segsz_bytes)
-{
-	snprintf(path, MAXPGPATH, XLOGDIR "/%08X%08X%08X.%08X.backup", tli,
-			 (uint32) (logSegNo / XLogSegmentsPerXLogId(wal_segsz_bytes)),
-			 (uint32) (logSegNo % XLogSegmentsPerXLogId(wal_segsz_bytes)),
-			 (uint32) (XLogSegmentOffset((startpoint), wal_segsz_bytes)));
-}
 
 /*
  * Information logged when we detect a change in one of the parameters
diff --git a/src/include/access/xlogfilepaths.h b/src/include/access/xlogfilepaths.h
new file mode 100644
index 0000000000..cdde2ccae4
--- /dev/null
+++ b/src/include/access/xlogfilepaths.h
@@ -0,0 +1,219 @@
+/*
+ * xlogfilepaths.h
+ *
+ * File name definitions and handling macros for PostgreSQL write-ahead logs.
+ *
+ * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/access/xlogfilepaths.h
+ */
+#ifndef XLOG_FILEPATHS_H
+#define XLOG_FILEPATHS_H
+
+#include "access/xlogdefs.h"
+
+/*
+ * The XLog directory and files (relative to $PGDATA)
+ */
+#define XLOGDIR					"pg_wal"
+
+/* control files */
+#define XLOG_CONTROL_FILE		"global/pg_control"
+#define BACKUP_LABEL_FILE		"backup_label"
+#define BACKUP_LABEL_OLD		"backup_label.old"
+
+/* tablespace map */
+#define TABLESPACE_MAP			"tablespace_map"
+#define TABLESPACE_MAP_OLD		"tablespace_map.old"
+
+/* files to signal run mode to standby */
+#define RECOVERY_SIGNAL_FILE	"recovery.signal"
+#define STANDBY_SIGNAL_FILE		"standby.signal"
+
+/* files to signal promotion to primary */
+#define PROMOTE_SIGNAL_FILE		"promote"
+
+/* wal_segment_size can range from 1MB to 1GB */
+#define WalSegMinSize 1024 * 1024
+#define WalSegMaxSize 1024 * 1024 * 1024
+
+/* default number of min and max wal segments */
+#define DEFAULT_MIN_WAL_SEGS 5
+#define DEFAULT_MAX_WAL_SEGS 64
+
+
+/*
+ * These macros encapsulate knowledge about the exact layout of XLog file
+ * names, timeline history file names, and archive-status file names.
+ */
+#define MAXFNAMELEN		64
+
+/* Length of XLog file name */
+#define XLOG_FNAME_LEN	   24
+
+/* check that the given size is a valid wal_segment_size */
+#define IsPowerOf2(x) (x > 0 && ((x) & ((x)-1)) == 0)
+#define IsValidWalSegSize(size) \
+	 (IsPowerOf2(size) && \
+	 ((size) >= WalSegMinSize && (size) <= WalSegMaxSize))
+
+/* Number of segments in a logical XLOG file */
+#define XLogSegmentsPerXLogId(wal_segsz_bytes)	\
+	(UINT64CONST(0x100000000) / (wal_segsz_bytes))
+
+/*
+ * Compute an XLogRecPtr from a segment number and offset.
+ */
+#define XLogSegNoOffsetToRecPtr(segno, offset, wal_segsz_bytes, dest) \
+		(dest) = (segno) * (wal_segsz_bytes) + (offset)
+/*
+ * Compute a segment number from an XLogRecPtr.
+ *
+ * For XLByteToSeg, do the computation at face value.  For XLByteToPrevSeg,
+ * a boundary byte is taken to be in the previous segment.  This is suitable
+ * for deciding which segment to write given a pointer to a record end,
+ * for example.
+ */
+#define XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes) \
+	logSegNo = (xlrp) / (wal_segsz_bytes)
+
+#define XLByteToPrevSeg(xlrp, logSegNo, wal_segsz_bytes) \
+	logSegNo = ((xlrp) - 1) / (wal_segsz_bytes)
+
+/* Compute the in-segment offset from an XLogRecPtr. */
+#define XLogSegmentOffset(xlogptr, wal_segsz_bytes)	\
+	((xlogptr) & ((wal_segsz_bytes) - 1))
+
+/*
+ * Convert values of GUCs measured in megabytes to equiv. segment count.
+ * Rounds down.
+ */
+#define XLogMBVarToSegs(mbvar, wal_segsz_bytes) \
+	((mbvar) / ((wal_segsz_bytes) / (1024 * 1024)))
+
+/*
+ * Is an XLogRecPtr within a particular XLOG segment?
+ *
+ * For XLByteInSeg, do the computation at face value.  For XLByteInPrevSeg,
+ * a boundary byte is taken to be in the previous segment.
+ */
+#define XLByteInSeg(xlrp, logSegNo, wal_segsz_bytes) \
+	(((xlrp) / (wal_segsz_bytes)) == (logSegNo))
+
+#define XLByteInPrevSeg(xlrp, logSegNo, wal_segsz_bytes) \
+	((((xlrp) - 1) / (wal_segsz_bytes)) == (logSegNo))
+
+/*
+ * XLOG file name handling functions
+ */
+static inline void
+StatusFilePath(char *path, const char *xlog, const char *suffix)
+{
+	snprintf(path, MAXPGPATH, XLOGDIR "/archive_status/%s%s", xlog, suffix);
+}
+
+static inline bool
+IsTLHistoryFileName(const char *fname)
+{
+	return (strlen(fname) == 8 + strlen(".history") &&
+			strspn(fname, "0123456789ABCDEF") == 8 &&
+			strcmp(fname + 8, ".history") == 0);
+}
+
+static inline void
+XLogFromFileName(const char *fname, TimeLineID *tli, XLogSegNo *logSegNo, int wal_segsz_bytes)
+{
+	uint32		log;
+	uint32		seg;
+
+	sscanf(fname, "%08X%08X%08X", tli, &log, &seg);
+	*logSegNo = (uint64) log * XLogSegmentsPerXLogId(wal_segsz_bytes) + seg;
+}
+
+static inline void
+XLogFilePath(char *path, TimeLineID tli, XLogSegNo logSegNo, int wal_segsz_bytes)
+{
+	snprintf(path, MAXPGPATH, XLOGDIR "/%08X%08X%08X", tli,
+			 (uint32) (logSegNo / XLogSegmentsPerXLogId(wal_segsz_bytes)),
+			 (uint32) (logSegNo % XLogSegmentsPerXLogId(wal_segsz_bytes)));
+}
+
+/*
+ * Generate a WAL segment file name.  Do not use this function in a helper
+ * function allocating the result generated.
+ */
+static inline void
+XLogFileName(char *fname, TimeLineID tli, XLogSegNo logSegNo, int wal_segsz_bytes)
+{
+	snprintf(fname, MAXFNAMELEN, "%08X%08X%08X", tli,
+			 (uint32) (logSegNo / XLogSegmentsPerXLogId(wal_segsz_bytes)),
+			 (uint32) (logSegNo % XLogSegmentsPerXLogId(wal_segsz_bytes)));
+}
+
+static inline void
+XLogFileNameById(char *fname, TimeLineID tli, uint32 log, uint32 seg)
+{
+	snprintf(fname, MAXFNAMELEN, "%08X%08X%08X", tli, log, seg);
+}
+
+static inline bool
+IsXLogFileName(const char *fname)
+{
+	return (strlen(fname) == XLOG_FNAME_LEN && \
+			strspn(fname, "0123456789ABCDEF") == XLOG_FNAME_LEN);
+}
+
+/*
+ * XLOG segment with .partial suffix.  Used by pg_receivewal and at end of
+ * archive recovery, when we want to archive a WAL segment but it might not
+ * be complete yet.
+ */
+static inline bool
+IsPartialXLogFileName(const char *fname)
+{
+	return (strlen(fname) == XLOG_FNAME_LEN + strlen(".partial") &&
+			strspn(fname, "0123456789ABCDEF") == XLOG_FNAME_LEN &&
+			strcmp(fname + XLOG_FNAME_LEN, ".partial") == 0);
+}
+
+static inline void
+TLHistoryFileName(char *fname, TimeLineID tli)
+{
+	snprintf(fname, MAXFNAMELEN, "%08X.history", tli);
+}
+
+static inline void
+TLHistoryFilePath(char *path, TimeLineID tli)
+{
+	snprintf(path, MAXPGPATH, XLOGDIR "/%08X.history", tli);
+}
+
+static inline void
+BackupHistoryFileName(char *fname, TimeLineID tli, XLogSegNo logSegNo, XLogRecPtr startpoint, int wal_segsz_bytes)
+{
+	snprintf(fname, MAXFNAMELEN, "%08X%08X%08X.%08X.backup", tli,
+			 (uint32) (logSegNo / XLogSegmentsPerXLogId(wal_segsz_bytes)),
+			 (uint32) (logSegNo % XLogSegmentsPerXLogId(wal_segsz_bytes)),
+			 (uint32) (XLogSegmentOffset(startpoint, wal_segsz_bytes)));
+}
+
+static inline bool
+IsBackupHistoryFileName(const char *fname)
+{
+	return (strlen(fname) > XLOG_FNAME_LEN &&
+			strspn(fname, "0123456789ABCDEF") == XLOG_FNAME_LEN &&
+			strcmp(fname + strlen(fname) - strlen(".backup"), ".backup") == 0);
+}
+
+static inline void
+BackupHistoryFilePath(char *path, TimeLineID tli, XLogSegNo logSegNo, XLogRecPtr startpoint, int wal_segsz_bytes)
+{
+	snprintf(path, MAXPGPATH, XLOGDIR "/%08X%08X%08X.%08X.backup", tli,
+			 (uint32) (logSegNo / XLogSegmentsPerXLogId(wal_segsz_bytes)),
+			 (uint32) (logSegNo % XLogSegmentsPerXLogId(wal_segsz_bytes)),
+			 (uint32) (XLogSegmentOffset((startpoint), wal_segsz_bytes)));
+}
+
+
+#endif							/* XLOG_FILEPATHS_H */
-- 
2.43.5

>From 813c3ff42886ecff5d038ffd5de44db488143841 Mon Sep 17 00:00:00 2001
From: "Anton A. Melnikov" <a.melni...@postgrespro.ru>
Date: Wed, 4 Sep 2024 16:23:23 +0900
Subject: [PATCH 2/2] Use XLOG_CONTROL_FILE macro everywhere in C code

---
 src/backend/backup/basebackup.c             | 2 +-
 src/backend/postmaster/postmaster.c         | 2 +-
 src/bin/pg_combinebackup/pg_combinebackup.c | 5 +++--
 src/bin/pg_controldata/pg_controldata.c     | 3 ++-
 src/bin/pg_rewind/filemap.c                 | 3 ++-
 src/bin/pg_rewind/pg_rewind.c               | 8 ++++----
 src/bin/pg_upgrade/controldata.c            | 9 +++++----
 src/bin/pg_verifybackup/pg_verifybackup.c   | 3 ++-
 src/common/controldata_utils.c              | 2 +-
 9 files changed, 21 insertions(+), 16 deletions(-)

diff --git a/src/backend/backup/basebackup.c b/src/backend/backup/basebackup.c
index 14e5ba72e9..bfa101b551 100644
--- a/src/backend/backup/basebackup.c
+++ b/src/backend/backup/basebackup.c
@@ -1348,7 +1348,7 @@ sendDir(bbsink *sink, const char *path, int basepathlen, bool sizeonly,
 		snprintf(pathbuf, sizeof(pathbuf), "%s/%s", path, de->d_name);
 
 		/* Skip pg_control here to back up it last */
-		if (strcmp(pathbuf, "./global/pg_control") == 0)
+		if (strcmp(pathbuf, "./" XLOG_CONTROL_FILE) == 0)
 			continue;
 
 		if (lstat(pathbuf, &statbuf) != 0)
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 96bc1d1cfe..bc5b0902c2 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -1463,7 +1463,7 @@ checkControlFile(void)
 	char		path[MAXPGPATH];
 	FILE	   *fp;
 
-	snprintf(path, sizeof(path), "%s/global/pg_control", DataDir);
+	snprintf(path, sizeof(path), "%s/%s", DataDir, XLOG_CONTROL_FILE);
 
 	fp = AllocateFile(path, PG_BINARY_R);
 	if (fp == NULL)
diff --git a/src/bin/pg_combinebackup/pg_combinebackup.c b/src/bin/pg_combinebackup/pg_combinebackup.c
index 6183d31715..def9a114d3 100644
--- a/src/bin/pg_combinebackup/pg_combinebackup.c
+++ b/src/bin/pg_combinebackup/pg_combinebackup.c
@@ -24,6 +24,7 @@
 #include <linux/fs.h>
 #endif
 
+#include "access/xlogfilepaths.h"
 #include "backup_label.h"
 #include "common/blkreftable.h"
 #include "common/checksum_helper.h"
@@ -296,7 +297,7 @@ main(int argc, char *argv[])
 		{
 			char	   *controlpath;
 
-			controlpath = psprintf("%s/%s", prior_backup_dirs[i], "global/pg_control");
+			controlpath = psprintf("%s/%s", prior_backup_dirs[i], XLOG_CONTROL_FILE);
 
 			pg_fatal("%s: manifest system identifier is %llu, but control file has %llu",
 					 controlpath,
@@ -605,7 +606,7 @@ check_control_files(int n_backups, char **backup_dirs)
 		bool		crc_ok;
 		char	   *controlpath;
 
-		controlpath = psprintf("%s/%s", backup_dirs[i], "global/pg_control");
+		controlpath = psprintf("%s/%s", backup_dirs[i], XLOG_CONTROL_FILE);
 		pg_log_debug("reading \"%s\"", controlpath);
 		control_file = get_controlfile_by_exact_path(controlpath, &crc_ok);
 
diff --git a/src/bin/pg_controldata/pg_controldata.c b/src/bin/pg_controldata/pg_controldata.c
index 233230712a..feba967221 100644
--- a/src/bin/pg_controldata/pg_controldata.c
+++ b/src/bin/pg_controldata/pg_controldata.c
@@ -1,7 +1,8 @@
 /*
  * pg_controldata
  *
- * reads the data from $PGDATA/global/pg_control
+ * reads the data from reads the data from the control file
+ * which is located at $PGDATA/XLOG_CONTROL_FILE
  *
  * copyright (c) Oliver Elphick <o...@lfix.co.uk>, 2001;
  * license: BSD
diff --git a/src/bin/pg_rewind/filemap.c b/src/bin/pg_rewind/filemap.c
index 00e644d988..dd4745f0bb 100644
--- a/src/bin/pg_rewind/filemap.c
+++ b/src/bin/pg_rewind/filemap.c
@@ -26,6 +26,7 @@
 #include <sys/stat.h>
 #include <unistd.h>
 
+#include "access/xlogfilepaths.h"
 #include "catalog/pg_tablespace_d.h"
 #include "common/file_utils.h"
 #include "common/hashfn_unstable.h"
@@ -643,7 +644,7 @@ decide_file_action(file_entry_t *entry)
 	 * Don't touch the control file. It is handled specially, after copying
 	 * all the other files.
 	 */
-	if (strcmp(path, "global/pg_control") == 0)
+	if (strcmp(path, XLOG_CONTROL_FILE) == 0)
 		return FILE_ACTION_NONE;
 
 	/* Skip macOS system files */
diff --git a/src/bin/pg_rewind/pg_rewind.c b/src/bin/pg_rewind/pg_rewind.c
index c4b97abd03..b683787fbe 100644
--- a/src/bin/pg_rewind/pg_rewind.c
+++ b/src/bin/pg_rewind/pg_rewind.c
@@ -328,7 +328,7 @@ main(int argc, char **argv)
 	 * need to make sure by themselves that the target cluster is in a clean
 	 * state.
 	 */
-	buffer = slurpFile(datadir_target, "global/pg_control", &size);
+	buffer = slurpFile(datadir_target, XLOG_CONTROL_FILE, &size);
 	digestControlFile(&ControlFile_target, buffer, size);
 	pg_free(buffer);
 
@@ -338,12 +338,12 @@ main(int argc, char **argv)
 	{
 		ensureCleanShutdown(argv[0]);
 
-		buffer = slurpFile(datadir_target, "global/pg_control", &size);
+		buffer = slurpFile(datadir_target, XLOG_CONTROL_FILE, &size);
 		digestControlFile(&ControlFile_target, buffer, size);
 		pg_free(buffer);
 	}
 
-	buffer = source->fetch_file(source, "global/pg_control", &size);
+	buffer = source->fetch_file(source, XLOG_CONTROL_FILE, &size);
 	digestControlFile(&ControlFile_source, buffer, size);
 	pg_free(buffer);
 
@@ -631,7 +631,7 @@ perform_rewind(filemap_t *filemap, rewind_source *source,
 	 * Fetch the control file from the source last. This ensures that the
 	 * minRecoveryPoint is up-to-date.
 	 */
-	buffer = source->fetch_file(source, "global/pg_control", &size);
+	buffer = source->fetch_file(source, XLOG_CONTROL_FILE, &size);
 	digestControlFile(&ControlFile_source_after, buffer, size);
 	pg_free(buffer);
 
diff --git a/src/bin/pg_upgrade/controldata.c b/src/bin/pg_upgrade/controldata.c
index 854c6887a2..7af0f82847 100644
--- a/src/bin/pg_upgrade/controldata.c
+++ b/src/bin/pg_upgrade/controldata.c
@@ -11,6 +11,7 @@
 
 #include <ctype.h>
 
+#include "access/xlogfilepaths.h"
 #include "common/string.h"
 #include "pg_upgrade.h"
 
@@ -715,10 +716,10 @@ disable_old_cluster(void)
 				new_path[MAXPGPATH];
 
 	/* rename pg_control so old server cannot be accidentally started */
-	prep_status("Adding \".old\" suffix to old global/pg_control");
+	prep_status("Adding \".old\" suffix to old " XLOG_CONTROL_FILE);
 
-	snprintf(old_path, sizeof(old_path), "%s/global/pg_control", old_cluster.pgdata);
-	snprintf(new_path, sizeof(new_path), "%s/global/pg_control.old", old_cluster.pgdata);
+	snprintf(old_path, sizeof(old_path), "%s/%s", old_cluster.pgdata, XLOG_CONTROL_FILE);
+	snprintf(new_path, sizeof(new_path), "%s/%s.old", old_cluster.pgdata, XLOG_CONTROL_FILE);
 	if (pg_mv_file(old_path, new_path) != 0)
 		pg_fatal("could not rename file \"%s\" to \"%s\": %m",
 				 old_path, new_path);
@@ -726,7 +727,7 @@ disable_old_cluster(void)
 
 	pg_log(PG_REPORT, "\n"
 		   "If you want to start the old cluster, you will need to remove\n"
-		   "the \".old\" suffix from %s/global/pg_control.old.\n"
+		   "the \".old\" suffix from %s/" XLOG_CONTROL_FILE ".old.\n"
 		   "Because \"link\" mode was used, the old cluster cannot be safely\n"
 		   "started once the new cluster has been started.",
 		   old_cluster.pgdata);
diff --git a/src/bin/pg_verifybackup/pg_verifybackup.c b/src/bin/pg_verifybackup/pg_verifybackup.c
index 3fcfb16721..dabce020a9 100644
--- a/src/bin/pg_verifybackup/pg_verifybackup.c
+++ b/src/bin/pg_verifybackup/pg_verifybackup.c
@@ -18,6 +18,7 @@
 #include <sys/stat.h>
 #include <time.h>
 
+#include "access/xlogfilepaths.h"
 #include "common/logging.h"
 #include "common/parse_manifest.h"
 #include "fe_utils/simple_list.h"
@@ -654,7 +655,7 @@ verify_backup_file(verifier_context *context, char *relpath, char *fullpath)
 	 * version 1.
 	 */
 	if (context->manifest->version != 1 &&
-		strcmp(relpath, "global/pg_control") == 0)
+		strcmp(relpath, XLOG_CONTROL_FILE) == 0)
 		verify_control_file(fullpath, context->manifest->system_identifier);
 
 	/* Update statistics for progress report, if necessary */
diff --git a/src/common/controldata_utils.c b/src/common/controldata_utils.c
index 82309b2510..411139eeb0 100644
--- a/src/common/controldata_utils.c
+++ b/src/common/controldata_utils.c
@@ -53,7 +53,7 @@ get_controlfile(const char *DataDir, bool *crc_ok_p)
 {
 	char		ControlFilePath[MAXPGPATH];
 
-	snprintf(ControlFilePath, MAXPGPATH, "%s/global/pg_control", DataDir);
+	snprintf(ControlFilePath, MAXPGPATH, "%s/%s", DataDir, XLOG_CONTROL_FILE);
 
 	return get_controlfile_by_exact_path(ControlFilePath, crc_ok_p);
 }
-- 
2.43.5

Reply via email to