Rebased all patches on the current master, renumbered them to be linear and marked as v3 version.With the best regards,
-- Anton A. Melnikov Postgres Professional: http://www.postgrespro.com The Russian Postgres Company
From 84ae0a626d5820f93a3423a518becb6dafc0a2af Mon Sep 17 00:00:00 2001 From: Kyotaro Horiguchi <horikyota....@gmail.com> Date: Wed, 4 Sep 2024 16:15:16 +0900 Subject: [PATCH] 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/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 ++++++++++++++++++ 14 files changed, 230 insertions(+), 198 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 a27f27cc037..710e92297e3 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 7e622ae4bd2..4db8a00b849 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 80bb807fbe9..af4c148c809 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 21a0fe3ecd9..f728e0fa802 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" #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 c25348bcb85..edf1828bc73 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 d4b4e334014..d981bb4c282 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 de3584018b0..4facc35f845 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/receivelog.c b/src/bin/pg_basebackup/receivelog.c index 6b6e32dfbdf..4f72ed42e11 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/logging.h" #include "libpq-fe.h" #include "receivelog.h" diff --git a/src/bin/pg_basebackup/streamutil.c b/src/bin/pg_basebackup/streamutil.c index 8e605f43ffe..62eb0586dc4 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/file_perm.h" #include "common/logging.h" diff --git a/src/bin/pg_controldata/pg_controldata.c b/src/bin/pg_controldata/pg_controldata.c index bea779eef94..162f087626d 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 2c8b1a07007..a625105fbcc 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 d313099c027..7ef9264fabc 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 */ @@ -299,16 +300,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 2cf8d55d706..5e846e48073 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 00000000000..cdde2ccae4f --- /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.48.1
From a0137b4a2f2437bb0a77c833c3fcf393c5364511 Mon Sep 17 00:00:00 2001 From: "Anton A. Melnikov" <a.melni...@postgrespro.ru> Date: Sat, 7 Sep 2024 10:18:51 +0300 Subject: [PATCH] Extract size-related macros from xlogfilepaths.h to xlogfilesize.h --- src/include/access/xlogfilepaths.h | 65 +---------------------- src/include/access/xlogfilesize.h | 83 ++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 63 deletions(-) create mode 100644 src/include/access/xlogfilesize.h diff --git a/src/include/access/xlogfilepaths.h b/src/include/access/xlogfilepaths.h index cdde2ccae4f..ed28cf975e6 100644 --- a/src/include/access/xlogfilepaths.h +++ b/src/include/access/xlogfilepaths.h @@ -12,6 +12,7 @@ #define XLOG_FILEPATHS_H #include "access/xlogdefs.h" +#include "access/xlogfilesize.h" /* * The XLog directory and files (relative to $PGDATA) @@ -34,75 +35,13 @@ /* 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. - */ +/* Maximum length of XLog file name including possible suffix */ #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 diff --git a/src/include/access/xlogfilesize.h b/src/include/access/xlogfilesize.h new file mode 100644 index 00000000000..fef30e02a62 --- /dev/null +++ b/src/include/access/xlogfilesize.h @@ -0,0 +1,83 @@ +/* + * xlogfilesize.h + * + * Size 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/xlogfilesize.h + */ + +#ifndef XLOG_FILESIZE_H +#define XLOG_FILESIZE_H + +#include "access/xlogdefs.h" + +/* 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 + * files, timeline history fils and archive-status fils. + */ + +/* 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)) + + +#endif /* XLOG_FILESIZE_H */ -- 2.48.1
From e55a0ab4fe3061f033de0d20becf0a9f2018b603 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] 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 3f8a3c55725..f0813eda8d7 100644 --- a/src/backend/backup/basebackup.c +++ b/src/backend/backup/basebackup.c @@ -1349,7 +1349,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 a0c37532d2f..7b5f6c37a95 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -1516,7 +1516,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 d480dc74436..bbf85144098 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/checksum_helper.h" #include "common/controldata_utils.h" @@ -300,7 +301,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, @@ -614,7 +615,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 162f087626d..d3714c629b3 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 a28d1667d4c..3ef38f329cb 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" @@ -704,7 +705,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 a625105fbcc..d32439fbfaf 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); @@ -636,7 +636,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 bd49ea867bf..6c070577003 100644 --- a/src/bin/pg_upgrade/controldata.c +++ b/src/bin/pg_upgrade/controldata.c @@ -12,6 +12,7 @@ #include <ctype.h> #include <limits.h> /* for CHAR_MIN */ +#include "access/xlogfilepaths.h" #include "common/string.h" #include "pg_upgrade.h" @@ -757,10 +758,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); @@ -768,7 +769,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 84edd2cdca5..df5466553fa 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" @@ -730,7 +731,7 @@ verify_plain_backup_file(verifier_context *context, char *relpath, * 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 34d8a3a4e31..fa375dc9129 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.48.1