Move WAL sequence code into its own file
authorMichael Paquier <michael@paquier.xyz>
Mon, 1 Dec 2025 07:21:41 +0000 (16:21 +0900)
committerMichael Paquier <michael@paquier.xyz>
Mon, 1 Dec 2025 07:21:41 +0000 (16:21 +0900)
This split exists for most of the other RMGRs, and makes cleaner the
separation between the WAL code, the redo code and the record
description code (already in its own file) when it comes to the sequence
RMGR.  The redo and masking routines are moved to a new file,
sequence_xlog.c.  All the RMGR routines are now located in a new header,
sequence_xlog.h.

This separation is useful for a different patch related to sequences
that I have been working on, where it makes a refactoring of sequence.c
easier if its RMGR routines and its core routines are split.

Reviewed-by: Heikki Linnakangas <hlinnaka@iki.fi>
Reviewed-by: Kirill Reshke <reshkekirill@gmail.com>
Discussion: https://postgr.es/m/aSfTxIWjiXkTKh1E@paquier.xyz

src/backend/access/rmgrdesc/seqdesc.c
src/backend/access/transam/rmgr.c
src/backend/commands/Makefile
src/backend/commands/meson.build
src/backend/commands/sequence.c
src/backend/commands/sequence_xlog.c [new file with mode: 0644]
src/bin/pg_waldump/rmgrdesc.c
src/include/commands/sequence.h
src/include/commands/sequence_xlog.h [new file with mode: 0644]

index 0d289d77fcf7a666339576c3764536e3f7c285fc..a0edb78856bdf93a50fcdeadb2f41fb1512e222b 100644 (file)
@@ -14,7 +14,7 @@
  */
 #include "postgres.h"
 
-#include "commands/sequence.h"
+#include "commands/sequence_xlog.h"
 
 
 void
index 1b7499726eb02df5c05d6522943ec9104aa1cd79..4fda03a3cfcc618b0144870a68b20d2ed895a707 100644 (file)
@@ -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"
index f99acfd2b4bbb32e4d2b4ea2590c09efe42306c6..64cb6278409ff14e3c7b0bfb9ffcb2ef5962c9c3 100644 (file)
@@ -53,6 +53,7 @@ OBJS = \
    schemacmds.o \
    seclabel.o \
    sequence.o \
+   sequence_xlog.o \
    statscmds.o \
    subscriptioncmds.o \
    tablecmds.o \
index 9f640ad48104c75da785c8f1a827968c95d05aa9..5fc35826b1cc34fffd3f350e33c894b34d5e9d53 100644 (file)
@@ -41,6 +41,7 @@ backend_sources += files(
   'schemacmds.c',
   'seclabel.c',
   'sequence.c',
+  'sequence_xlog.c',
   'statscmds.c',
   'subscriptioncmds.c',
   'tablecmds.c',
index 8d671b7a29d6375679417a89b6080ab1b8b05d3b..51567994126f4aea0431358ee0bc187144baeb21 100644 (file)
@@ -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"
 #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"
  */
 #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 (file)
index 0000000..ffbd982
--- /dev/null
@@ -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);
+}
index fac509ed134e5190eed5cb3eb4a52ff35a0a14b9..931ab8b979e230debb4e2508206c266e113b85b2 100644 (file)
@@ -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"
index 46b4d89dd6eafb1349c79f8cb1516c3cc6a3a1b3..3f8d353c49e7f84ff92dab017f33be5ce93e734a 100644 (file)
 #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 (file)
index 0000000..c8cf011
--- /dev/null
@@ -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 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 */