From: Michael Paquier Date: Mon, 2 Mar 2026 05:13:05 +0000 (+0900) Subject: Remove WAL page header flag XLP_BKP_REMOVABLE X-Git-Tag: REL_19_BETA1~974 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f68d7e7483d240d8c92b8fc245a3a10199d426dd;p=thirdparty%2Fpostgresql.git Remove WAL page header flag XLP_BKP_REMOVABLE There are no known users of this flag. The last supposed user was pglesslog, which is the reason why this flag has been introduced in core, based on an historical search pointing at a8d539f12498. I have mentioned that we may want to remove this flag back in 2018, due to zero users of it in core. More recently, Noah has pointed out that this flag is not safe to use: XLP_BKP_REMOVABLE can be set by the WAL writer in a lock-free fashion with runningBackups > 0, meaning that some full-page images could be required but not logged, ultimately corrupting backups. Bump XLOG_PAGE_MAGIC. Author: Matthias van de Meent Discussion: https://postgr.es/m/20250705001628.c3.nmisch@google.com Discussion: https://postgr.es/m/CAEze2WhiwKSoAvfUggjDeoeY0-rz9cTpfrHcqvBMmJxv-K_5DA@mail.gmail.com --- diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 13cce9b49f1..354ac645bdc 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -1990,7 +1990,6 @@ XLogRecPtrToBytePos(XLogRecPtr ptr) static void AdvanceXLInsertBuffer(XLogRecPtr upto, TimeLineID tli, bool opportunistic) { - XLogCtlInsert *Insert = &XLogCtl->Insert; int nextidx; XLogRecPtr OldPageRqstPtr; XLogwrtRqst WriteRqst; @@ -2114,22 +2113,6 @@ AdvanceXLInsertBuffer(XLogRecPtr upto, TimeLineID tli, bool opportunistic) /* NewPage->xlp_rem_len = 0; */ /* done by memset */ - /* - * If online backup is not in progress, mark the header to indicate - * that WAL records beginning in this page have removable backup - * blocks. This allows the WAL archiver to know whether it is safe to - * compress archived WAL data by transforming full-block records into - * the non-full-block format. It is sufficient to record this at the - * page level because we force a page switch (in fact a segment - * switch) when starting a backup, so the flag will be off before any - * records can be written during the backup. At the end of a backup, - * the last page will be marked as all unsafe when perhaps only part - * is unsafe, but at worst the archiver would miss the opportunity to - * compress a few records. - */ - if (Insert->runningBackups == 0) - NewPage->xlp_info |= XLP_BKP_REMOVABLE; - /* * If first page of an XLOG segment file, make it a long header. */ @@ -9037,12 +9020,6 @@ do_pg_backup_start(const char *backupidstr, bool fast, List **tablespaces, * pg_wal directory was not included in the base backup and the WAL * archive was cleared too before starting the backup. * - * This also ensures that we have emitted a WAL page header that has - * XLP_BKP_REMOVABLE off before we emit the checkpoint record. - * Therefore, if a WAL archiver (such as pglesslog) is trying to - * compress out removable backup blocks, it won't remove any that - * occur after this point. - * * During recovery, we skip forcing XLOG file switch, which means that * the backup taken during recovery is not available for the special * recovery case described above. diff --git a/src/include/access/xlog_internal.h b/src/include/access/xlog_internal.h index fbc5d77ab39..58ae12bb20f 100644 --- a/src/include/access/xlog_internal.h +++ b/src/include/access/xlog_internal.h @@ -31,7 +31,7 @@ /* * Each page of XLOG file has a header like this: */ -#define XLOG_PAGE_MAGIC 0xD11B /* can be used as WAL version indicator */ +#define XLOG_PAGE_MAGIC 0xD11C /* can be used as WAL version indicator */ typedef struct XLogPageHeaderData { @@ -74,12 +74,10 @@ typedef XLogLongPageHeaderData *XLogLongPageHeader; #define XLP_FIRST_IS_CONTRECORD 0x0001 /* This flag indicates a "long" page header */ #define XLP_LONG_HEADER 0x0002 -/* This flag indicates backup blocks starting in this page are optional */ -#define XLP_BKP_REMOVABLE 0x0004 /* Replaces a missing contrecord; see CreateOverwriteContrecordRecord */ -#define XLP_FIRST_IS_OVERWRITE_CONTRECORD 0x0008 +#define XLP_FIRST_IS_OVERWRITE_CONTRECORD 0x0004 /* All defined flag bits in xlp_info (used for validity checking of header) */ -#define XLP_ALL_FLAGS 0x000F +#define XLP_ALL_FLAGS 0x0007 #define XLogPageHeaderSize(hdr) \ (((hdr)->xlp_info & XLP_LONG_HEADER) ? SizeOfXLogLongPHD : SizeOfXLogShortPHD)