Hi all,

Something that has been bugging me in the sequence code, while doing
some recent work (cough), is the fact that it is possible to cleanly
split the RMGR sequence code from the main sequence.c.

Please find attached a patch doing that, cleaning a bit sequence.c by
removing some of the WAL bits in it, as of:
- Addition of a new file sequence_xlog.c.
- Addition of a new header, sequence_xlog.h.

SEQ_MAGIC and sequence_magic need to be moved from sequence.c to the
new sequence_xlog.h, separating the WAL insert code with the backend
redo parts of it, which is more consistent with other RMGRs.

I have been looking at some other parts of the backend (like the
tablespace part), but these don't really bring a clear gain like the
change in the attached does.

Thanks,
--
Michael
From 00ce1d2bf53744125e4f8bd900de234150fb8a9d Mon Sep 17 00:00:00 2001
From: Michael Paquier <[email protected]>
Date: Thu, 27 Nov 2025 12:50:01 +0900
Subject: [PATCH] Move WAL sequence code into its own file

This split exists for most of the other RMGRs, and makes cleaner the
separation between WAL code, redo code and record description code
(already in its own file).
---
 src/include/commands/sequence.h       | 18 ------
 src/include/commands/sequence_xlog.h  | 45 +++++++++++++++
 src/backend/access/rmgrdesc/seqdesc.c |  2 +-
 src/backend/access/transam/rmgr.c     |  2 +-
 src/backend/commands/Makefile         |  1 +
 src/backend/commands/meson.build      |  1 +
 src/backend/commands/sequence.c       | 76 +------------------------
 src/backend/commands/sequence_xlog.c  | 80 +++++++++++++++++++++++++++
 src/bin/pg_waldump/rmgrdesc.c         |  2 +-
 9 files changed, 132 insertions(+), 95 deletions(-)
 create mode 100644 src/include/commands/sequence_xlog.h
 create mode 100644 src/backend/commands/sequence_xlog.c

diff --git a/src/include/commands/sequence.h b/src/include/commands/sequence.h
index 46b4d89dd6ea..3f8d353c49e7 100644
--- a/src/include/commands/sequence.h
+++ b/src/include/commands/sequence.h
@@ -13,14 +13,10 @@
 #ifndef SEQUENCE_H
 #define SEQUENCE_H
 
-#include "access/xlogreader.h"
 #include "catalog/objectaddress.h"
 #include "fmgr.h"
-#include "lib/stringinfo.h"
 #include "nodes/parsenodes.h"
 #include "parser/parse_node.h"
-#include "storage/relfilelocator.h"
-
 
 typedef struct FormData_pg_sequence_data
 {
@@ -42,15 +38,6 @@ typedef FormData_pg_sequence_data *Form_pg_sequence_data;
 #define SEQ_COL_FIRSTCOL		SEQ_COL_LASTVAL
 #define SEQ_COL_LASTCOL			SEQ_COL_CALLED
 
-/* XLOG stuff */
-#define XLOG_SEQ_LOG			0x00
-
-typedef struct xl_seq_rec
-{
-	RelFileLocator locator;
-	/* SEQUENCE TUPLE DATA FOLLOWS AT THE END */
-} xl_seq_rec;
-
 extern int64 nextval_internal(Oid relid, bool check_permissions);
 extern Datum nextval(PG_FUNCTION_ARGS);
 extern List *sequence_options(Oid relid);
@@ -63,9 +50,4 @@ extern void ResetSequence(Oid seq_relid);
 extern void SetSequence(Oid relid, int64 next, bool is_called);
 extern void ResetSequenceCaches(void);
 
-extern void seq_redo(XLogReaderState *record);
-extern void seq_desc(StringInfo buf, XLogReaderState *record);
-extern const char *seq_identify(uint8 info);
-extern void seq_mask(char *page, BlockNumber blkno);
-
 #endif							/* SEQUENCE_H */
diff --git a/src/include/commands/sequence_xlog.h b/src/include/commands/sequence_xlog.h
new file mode 100644
index 000000000000..88453b382fb0
--- /dev/null
+++ b/src/include/commands/sequence_xlog.h
@@ -0,0 +1,45 @@
+/*-------------------------------------------------------------------------
+ *
+ * sequence_xlog.h
+ *	  Sequence WAL definitions.
+ *
+ * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/commands/sequence_xlog.h
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#ifndef SEQUENCE_XLOG_H
+#define SEQUENCE_XLOG_H
+
+#include "access/xlogreader.h"
+#include "lib/stringinfo.h"
+
+/* Record identifier */
+#define XLOG_SEQ_LOG			0x00
+
+/*
+ * The "special area" of a local sequence's buffer page looks like this.
+ */
+#define SEQ_MAGIC		0x1717
+
+typedef struct sequence_magic
+{
+	uint32		magic;
+} sequence_magic;
+
+/* Sequence WAL record */
+typedef struct xl_seq_rec
+{
+	RelFileLocator locator;
+	/* SEQUENCE TUPLE DATA FOLLOWS AT THE END */
+} xl_seq_rec;
+
+extern void seq_redo(XLogReaderState *record);
+extern void seq_desc(StringInfo buf, XLogReaderState *record);
+extern const char *seq_identify(uint8 info);
+extern void seq_mask(char *page, BlockNumber blkno);
+
+#endif							/* SEQUENCE_XLOG_H */
diff --git a/src/backend/access/rmgrdesc/seqdesc.c b/src/backend/access/rmgrdesc/seqdesc.c
index 0d289d77fcf7..a0edb78856bd 100644
--- a/src/backend/access/rmgrdesc/seqdesc.c
+++ b/src/backend/access/rmgrdesc/seqdesc.c
@@ -14,7 +14,7 @@
  */
 #include "postgres.h"
 
-#include "commands/sequence.h"
+#include "commands/sequence_xlog.h"
 
 
 void
diff --git a/src/backend/access/transam/rmgr.c b/src/backend/access/transam/rmgr.c
index 1b7499726eb0..4fda03a3cfcc 100644
--- a/src/backend/access/transam/rmgr.c
+++ b/src/backend/access/transam/rmgr.c
@@ -33,7 +33,7 @@
 #include "access/xact.h"
 #include "catalog/storage_xlog.h"
 #include "commands/dbcommands_xlog.h"
-#include "commands/sequence.h"
+#include "commands/sequence_xlog.h"
 #include "commands/tablespace.h"
 #include "replication/decode.h"
 #include "replication/message.h"
diff --git a/src/backend/commands/Makefile b/src/backend/commands/Makefile
index f99acfd2b4bb..64cb6278409f 100644
--- a/src/backend/commands/Makefile
+++ b/src/backend/commands/Makefile
@@ -53,6 +53,7 @@ OBJS = \
 	schemacmds.o \
 	seclabel.o \
 	sequence.o \
+	sequence_xlog.o \
 	statscmds.o \
 	subscriptioncmds.o \
 	tablecmds.o \
diff --git a/src/backend/commands/meson.build b/src/backend/commands/meson.build
index 9f640ad48104..5fc35826b1cc 100644
--- a/src/backend/commands/meson.build
+++ b/src/backend/commands/meson.build
@@ -41,6 +41,7 @@ backend_sources += files(
   'schemacmds.c',
   'seclabel.c',
   'sequence.c',
+  'sequence_xlog.c',
   'statscmds.c',
   'subscriptioncmds.c',
   'tablecmds.c',
diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c
index 8d671b7a29d6..51567994126f 100644
--- a/src/backend/commands/sequence.c
+++ b/src/backend/commands/sequence.c
@@ -14,7 +14,6 @@
  */
 #include "postgres.h"
 
-#include "access/bufmask.h"
 #include "access/htup_details.h"
 #include "access/multixact.h"
 #include "access/relation.h"
@@ -22,9 +21,7 @@
 #include "access/table.h"
 #include "access/transam.h"
 #include "access/xact.h"
-#include "access/xlog.h"
 #include "access/xloginsert.h"
-#include "access/xlogutils.h"
 #include "catalog/dependency.h"
 #include "catalog/indexing.h"
 #include "catalog/namespace.h"
@@ -34,11 +31,13 @@
 #include "catalog/storage_xlog.h"
 #include "commands/defrem.h"
 #include "commands/sequence.h"
+#include "commands/sequence_xlog.h"
 #include "commands/tablecmds.h"
 #include "funcapi.h"
 #include "miscadmin.h"
 #include "nodes/makefuncs.h"
 #include "parser/parse_type.h"
+#include "storage/bufmgr.h"
 #include "storage/lmgr.h"
 #include "storage/proc.h"
 #include "storage/smgr.h"
@@ -58,16 +57,6 @@
  */
 #define SEQ_LOG_VALS	32
 
-/*
- * The "special area" of a sequence's buffer page looks like this.
- */
-#define SEQ_MAGIC	  0x1717
-
-typedef struct sequence_magic
-{
-	uint32		magic;
-} sequence_magic;
-
 /*
  * We store a SeqTable item for every sequence we have touched in the current
  * session.  This is needed to hold onto nextval/currval state.  (We can't
@@ -1907,56 +1896,6 @@ pg_sequence_last_value(PG_FUNCTION_ARGS)
 		PG_RETURN_NULL();
 }
 
-
-void
-seq_redo(XLogReaderState *record)
-{
-	XLogRecPtr	lsn = record->EndRecPtr;
-	uint8		info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
-	Buffer		buffer;
-	Page		page;
-	Page		localpage;
-	char	   *item;
-	Size		itemsz;
-	xl_seq_rec *xlrec = (xl_seq_rec *) XLogRecGetData(record);
-	sequence_magic *sm;
-
-	if (info != XLOG_SEQ_LOG)
-		elog(PANIC, "seq_redo: unknown op code %u", info);
-
-	buffer = XLogInitBufferForRedo(record, 0);
-	page = BufferGetPage(buffer);
-
-	/*
-	 * We always reinit the page.  However, since this WAL record type is also
-	 * used for updating sequences, it's possible that a hot-standby backend
-	 * is examining the page concurrently; so we mustn't transiently trash the
-	 * buffer.  The solution is to build the correct new page contents in
-	 * local workspace and then memcpy into the buffer.  Then only bytes that
-	 * are supposed to change will change, even transiently. We must palloc
-	 * the local page for alignment reasons.
-	 */
-	localpage = (Page) palloc(BufferGetPageSize(buffer));
-
-	PageInit(localpage, BufferGetPageSize(buffer), sizeof(sequence_magic));
-	sm = (sequence_magic *) PageGetSpecialPointer(localpage);
-	sm->magic = SEQ_MAGIC;
-
-	item = (char *) xlrec + sizeof(xl_seq_rec);
-	itemsz = XLogRecGetDataLen(record) - sizeof(xl_seq_rec);
-
-	if (PageAddItem(localpage, item, itemsz, FirstOffsetNumber, false, false) == InvalidOffsetNumber)
-		elog(PANIC, "seq_redo: failed to add item to page");
-
-	PageSetLSN(localpage, lsn);
-
-	memcpy(page, localpage, BufferGetPageSize(buffer));
-	MarkBufferDirty(buffer);
-	UnlockReleaseBuffer(buffer);
-
-	pfree(localpage);
-}
-
 /*
  * Flush cached sequence information.
  */
@@ -1971,14 +1910,3 @@ ResetSequenceCaches(void)
 
 	last_used_seq = NULL;
 }
-
-/*
- * Mask a Sequence page before performing consistency checks on it.
- */
-void
-seq_mask(char *page, BlockNumber blkno)
-{
-	mask_page_lsn_and_checksum(page);
-
-	mask_unused_space(page);
-}
diff --git a/src/backend/commands/sequence_xlog.c b/src/backend/commands/sequence_xlog.c
new file mode 100644
index 000000000000..ffbd9820416a
--- /dev/null
+++ b/src/backend/commands/sequence_xlog.c
@@ -0,0 +1,80 @@
+/*-------------------------------------------------------------------------
+ *
+ * sequence.c
+ *	  RMGR WAL routines for sequences.
+ *
+ * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ *
+ * IDENTIFICATION
+ *	  src/backend/commands/sequence_xlog.c
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "postgres.h"
+
+#include "access/bufmask.h"
+#include "access/xlogutils.h"
+#include "commands/sequence_xlog.h"
+#include "storage/bufmgr.h"
+
+void
+seq_redo(XLogReaderState *record)
+{
+	XLogRecPtr	lsn = record->EndRecPtr;
+	uint8		info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
+	Buffer		buffer;
+	Page		page;
+	Page		localpage;
+	char	   *item;
+	Size		itemsz;
+	xl_seq_rec *xlrec = (xl_seq_rec *) XLogRecGetData(record);
+	sequence_magic *sm;
+
+	if (info != XLOG_SEQ_LOG)
+		elog(PANIC, "seq_redo: unknown op code %u", info);
+
+	buffer = XLogInitBufferForRedo(record, 0);
+	page = BufferGetPage(buffer);
+
+	/*
+	 * We always reinit the page.  However, since this WAL record type is also
+	 * used for updating sequences, it's possible that a hot-standby backend
+	 * is examining the page concurrently; so we mustn't transiently trash the
+	 * buffer.  The solution is to build the correct new page contents in
+	 * local workspace and then memcpy into the buffer.  Then only bytes that
+	 * are supposed to change will change, even transiently. We must palloc
+	 * the local page for alignment reasons.
+	 */
+	localpage = (Page) palloc(BufferGetPageSize(buffer));
+
+	PageInit(localpage, BufferGetPageSize(buffer), sizeof(sequence_magic));
+	sm = (sequence_magic *) PageGetSpecialPointer(localpage);
+	sm->magic = SEQ_MAGIC;
+
+	item = (char *) xlrec + sizeof(xl_seq_rec);
+	itemsz = XLogRecGetDataLen(record) - sizeof(xl_seq_rec);
+
+	if (PageAddItem(localpage, item, itemsz, FirstOffsetNumber, false, false) == InvalidOffsetNumber)
+		elog(PANIC, "seq_redo: failed to add item to page");
+
+	PageSetLSN(localpage, lsn);
+
+	memcpy(page, localpage, BufferGetPageSize(buffer));
+	MarkBufferDirty(buffer);
+	UnlockReleaseBuffer(buffer);
+
+	pfree(localpage);
+}
+
+/*
+ * Mask a Sequence page before performing consistency checks on it.
+ */
+void
+seq_mask(char *page, BlockNumber blkno)
+{
+	mask_page_lsn_and_checksum(page);
+
+	mask_unused_space(page);
+}
diff --git a/src/bin/pg_waldump/rmgrdesc.c b/src/bin/pg_waldump/rmgrdesc.c
index fac509ed134e..931ab8b979e2 100644
--- a/src/bin/pg_waldump/rmgrdesc.c
+++ b/src/bin/pg_waldump/rmgrdesc.c
@@ -24,7 +24,7 @@
 #include "access/xlog_internal.h"
 #include "catalog/storage_xlog.h"
 #include "commands/dbcommands_xlog.h"
-#include "commands/sequence.h"
+#include "commands/sequence_xlog.h"
 #include "commands/tablespace.h"
 #include "replication/message.h"
 #include "replication/origin.h"
-- 
2.51.0

Attachment: signature.asc
Description: PGP signature

Reply via email to