v1-0005-Stop-the-logging-of-XIDs-in-records-where-the-XID.patch

application/octet-stream

Filename: v1-0005-Stop-the-logging-of-XIDs-in-records-where-the-XID.patch
Type: application/octet-stream
Part: 2
Message: XLog size reductions: Reduced XLog record header size for PG17

Patch

Same data as JSON: GET /api/v1/attachments/:id/patch the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes. API reference →
Format: format-patch
Series: patch v1-0005
Subject: Stop the logging of XIDs in records where the XID is unused.
File+
src/backend/access/heap/heapam.c 9 7
src/backend/access/heap/pruneheap.c 1 0
src/backend/access/heap/rewriteheap.c 1 0
src/backend/access/transam/generic_xlog.c 3 0
src/backend/access/transam/multixact.c 1 0
src/backend/access/transam/xact.c 2 2
src/backend/access/transam/xloginsert.c 10 2
src/backend/commands/tablecmds.c 1 1
src/backend/replication/logical/message.c 1 1
src/backend/utils/cache/inval.c 1 0
src/include/access/xlog.h 1 0
From 501ace5f11cb90101b3a770de3ada9f541af698c Mon Sep 17 00:00:00 2001
From: Matthias van de Meent <boekewurm+postgres@gmail.com>
Date: Wed, 25 Jan 2023 15:40:30 +0100
Subject: [PATCH v1 5/6] Stop the logging of XIDs in records where the XID is
 unused.

Many WAL record types do not need to contain an XID. This change
prepares for the removal of the xid from the main xlog record header,
by requiring the user of the XLog insertion API to explicitly request
the inclusion of the current xid in the log record - in all other
cases we'll log, assume and track InvalidXid instead.
---
 src/backend/access/heap/heapam.c          | 16 +++++++++-------
 src/backend/access/heap/pruneheap.c       |  1 +
 src/backend/access/heap/rewriteheap.c     |  1 +
 src/backend/access/transam/generic_xlog.c |  3 +++
 src/backend/access/transam/multixact.c    |  1 +
 src/backend/access/transam/xact.c         |  4 ++--
 src/backend/access/transam/xloginsert.c   | 12 ++++++++++--
 src/backend/commands/tablecmds.c          |  2 +-
 src/backend/replication/logical/message.c |  2 +-
 src/backend/utils/cache/inval.c           |  1 +
 src/include/access/xlog.h                 |  1 +
 11 files changed, 31 insertions(+), 13 deletions(-)

diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index 2a2525cee9..c9f3dbf9ca 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -1969,7 +1969,7 @@ heap_insert(Relation relation, HeapTuple tup, CommandId cid,
 							heaptup->t_len - SizeofHeapTupleHeader);
 
 		/* filtering by origin on a row level is much more efficient */
-		XLogSetRecordFlags(XLOG_INCLUDE_ORIGIN);
+		XLogSetRecordFlags(XLOG_INCLUDE_ORIGIN | XLOG_INCLUDE_XID);
 
 		recptr = XLogInsert(RM_HEAP_ID, info);
 
@@ -2365,7 +2365,7 @@ heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples,
 			XLogRegisterBufData(0, tupledata, totaldatalen);
 
 			/* filtering by origin on a row level is much more efficient */
-			XLogSetRecordFlags(XLOG_INCLUDE_ORIGIN);
+			XLogSetRecordFlags(XLOG_INCLUDE_ORIGIN | XLOG_INCLUDE_XID);
 
 			recptr = XLogInsert(RM_HEAP2_ID, info);
 
@@ -2865,7 +2865,7 @@ l1:
 		}
 
 		/* filtering by origin on a row level is much more efficient */
-		XLogSetRecordFlags(XLOG_INCLUDE_ORIGIN);
+		XLogSetRecordFlags(XLOG_INCLUDE_ORIGIN | XLOG_INCLUDE_XID);
 
 		recptr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_DELETE);
 
@@ -5535,6 +5535,7 @@ l4:
 				cleared_all_frozen ? XLH_LOCK_ALL_FROZEN_CLEARED : 0;
 
 			XLogRegisterData((char *) &xlrec, SizeOfHeapLockUpdated);
+			XLogSetRecordFlags(XLOG_INCLUDE_XID);
 
 			recptr = XLogInsert(RM_HEAP2_ID, XLOG_HEAP2_LOCK_UPDATED);
 
@@ -5685,7 +5686,7 @@ heap_finish_speculative(Relation relation, ItemPointer tid)
 		XLogBeginInsert();
 
 		/* We want the same filtering on this as on a plain insert */
-		XLogSetRecordFlags(XLOG_INCLUDE_ORIGIN);
+		XLogSetRecordFlags(XLOG_INCLUDE_ORIGIN | XLOG_INCLUDE_XID);
 
 		XLogRegisterData((char *) &xlrec, SizeOfHeapConfirm);
 		XLogRegisterBuffer(0, buffer, REGBUF_STANDARD);
@@ -5831,7 +5832,8 @@ heap_abort_speculative(Relation relation, ItemPointer tid)
 		XLogRegisterData((char *) &xlrec, SizeOfHeapDelete);
 		XLogRegisterBuffer(0, buffer, REGBUF_STANDARD);
 
-		/* No replica identity & replication origin logged */
+		/* No replica identity & replication origin logged, but XID is required */
+		XLogSetRecordFlags(XLOG_INCLUDE_XID);
 
 		recptr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_DELETE);
 
@@ -8563,7 +8565,7 @@ log_heap_update(Relation reln, Buffer oldbuf,
 	}
 
 	/* filtering by origin on a row level is much more efficient */
-	XLogSetRecordFlags(XLOG_INCLUDE_ORIGIN);
+	XLogSetRecordFlags(XLOG_INCLUDE_ORIGIN | XLOG_INCLUDE_XID);
 
 	recptr = XLogInsert(RM_HEAP_ID, info);
 
@@ -8638,7 +8640,7 @@ log_heap_new_cid(Relation relation, HeapTuple tup)
 	XLogRegisterData((char *) &xlrec, SizeOfHeapNewCid);
 
 	/* will be looked at irrespective of origin */
-
+	XLogSetRecordFlags(XLOG_INCLUDE_XID);
 	recptr = XLogInsert(RM_HEAP2_ID, XLOG_HEAP2_NEW_CID);
 
 	return recptr;
diff --git a/src/backend/access/heap/pruneheap.c b/src/backend/access/heap/pruneheap.c
index 20df39c149..36459e75a1 100644
--- a/src/backend/access/heap/pruneheap.c
+++ b/src/backend/access/heap/pruneheap.c
@@ -445,6 +445,7 @@ heap_page_prune(Relation relation, Buffer buffer,
 				XLogRegisterBufData(0, (char *) prstate.nowunused,
 									prstate.nunused * sizeof(OffsetNumber));
 
+			XLogSetRecordFlags(XLOG_INCLUDE_XID);
 			recptr = XLogInsert(RM_HEAP2_ID, XLOG_HEAP2_PRUNE);
 
 			PageSetLSN(BufferGetPage(buffer), recptr);
diff --git a/src/backend/access/heap/rewriteheap.c b/src/backend/access/heap/rewriteheap.c
index 424958912c..9f77537335 100644
--- a/src/backend/access/heap/rewriteheap.c
+++ b/src/backend/access/heap/rewriteheap.c
@@ -921,6 +921,7 @@ logical_heap_rewrite_flush_mappings(RewriteState state)
 		src->off += len;
 
 		XLogBeginInsert();
+		XLogSetRecordFlags(XLOG_INCLUDE_XID);
 		XLogRegisterData((char *) (&xlrec), sizeof(xlrec));
 		XLogRegisterData(waldata_start, len);
 
diff --git a/src/backend/access/transam/generic_xlog.c b/src/backend/access/transam/generic_xlog.c
index 6c68191ca6..c8983b40ad 100644
--- a/src/backend/access/transam/generic_xlog.c
+++ b/src/backend/access/transam/generic_xlog.c
@@ -399,6 +399,9 @@ GenericXLogFinish(GenericXLogState *state)
 			}
 		}
 
+		/* Assume XID is required */
+		XLogSetRecordFlags(XLOG_INCLUDE_XID);
+
 		/* Insert xlog record */
 		lsn = XLogInsert(RM_GENERIC_ID, 0);
 
diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c
index 4e1244541d..e2ff98a1d0 100644
--- a/src/backend/access/transam/multixact.c
+++ b/src/backend/access/transam/multixact.c
@@ -834,6 +834,7 @@ MultiXactIdCreateFromMembers(int nmembers, MultiXactMember *members)
 	 * Not clear that it's worth the trouble though.
 	 */
 	XLogBeginInsert();
+	XLogSetRecordFlags(XLOG_INCLUDE_XID);
 	XLogRegisterData((char *) (&xlrec), SizeOfMultiXactCreate);
 	XLogRegisterData((char *) members, nmembers * sizeof(MultiXactMember));
 
diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c
index a70cb3e124..003f12a97d 100644
--- a/src/backend/access/transam/xact.c
+++ b/src/backend/access/transam/xact.c
@@ -5794,7 +5794,7 @@ XactLogCommitRecord(TimestampTz commit_time,
 		XLogRegisterData((char *) (&xl_origin), sizeof(xl_xact_origin));
 
 	/* we allow filtering by xacts */
-	XLogSetRecordFlags(XLOG_INCLUDE_ORIGIN);
+	XLogSetRecordFlags(XLOG_INCLUDE_ORIGIN | XLOG_INCLUDE_XID);
 
 	return XLogInsertExtended(RM_XACT_ID, info, rmgr_info);
 }
@@ -5941,7 +5941,7 @@ XactLogAbortRecord(TimestampTz abort_time,
 		XLogRegisterData((char *) (&xl_origin), sizeof(xl_xact_origin));
 
 	/* Include the replication origin */
-	XLogSetRecordFlags(XLOG_INCLUDE_ORIGIN);
+	XLogSetRecordFlags(XLOG_INCLUDE_ORIGIN | XLOG_INCLUDE_XID);
 
 	return XLogInsertExtended(RM_XACT_ID, info, rmgr_info);
 }
diff --git a/src/backend/access/transam/xloginsert.c b/src/backend/access/transam/xloginsert.c
index 76b508d535..b105d90e3f 100644
--- a/src/backend/access/transam/xloginsert.c
+++ b/src/backend/access/transam/xloginsert.c
@@ -456,6 +456,10 @@ XLogSetRecordFlags(uint8 flags)
  * (LSN is the XLOG point up to which the XLOG must be flushed to disk
  * before the data page can be written out.  This implements the basic
  * WAL rule "write the log before the data".)
+ *
+ * Note: To include the current backend's TransactionID in the record,
+ * you have to set the XLOG_INCLUDE_XID flag using XLogRecordSetFlags
+ * before calling XLogInsert.
  */
 XLogRecPtr
 XLogInsert(RmgrId rmid, uint8 rmgr_info)
@@ -847,7 +851,7 @@ XLogRecordAssemble(RmgrId rmid, uint8 info, uint8 rmgr_info, XLogRecPtr RedoRecP
 	}
 
 	/* followed by toplevel XID, if not already included in previous record */
-	if (IsSubxactTopXidLogPending())
+	if (curinsert_flags & XLOG_INCLUDE_XID && IsSubxactTopXidLogPending())
 	{
 		TransactionId xid = GetTopTransactionIdIfAny();
 
@@ -924,7 +928,11 @@ XLogRecordAssemble(RmgrId rmid, uint8 info, uint8 rmgr_info, XLogRecPtr RedoRecP
 	 * once we know where in the WAL the record will be inserted. The CRC does
 	 * not include the record header yet.
 	 */
-	rechdr->xl_xid = GetCurrentTransactionIdIfAny();
+	if (curinsert_flags & XLOG_INCLUDE_XID)
+		rechdr->xl_xid = GetCurrentTransactionIdIfAny();
+	else
+		rechdr->xl_xid = InvalidTransactionId;
+
 	rechdr->xl_tot_len = (uint32) total_len;
 	rechdr->xl_info = info;
 	rechdr->xl_rmid = rmid;
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index c7a8a689b7..deeb905942 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -2132,7 +2132,7 @@ ExecuteTruncateGuts(List *explicit_rels,
 		XLogRegisterData((char *) &xlrec, SizeOfHeapTruncate);
 		XLogRegisterData((char *) logrelids, list_length(relids_logged) * sizeof(Oid));
 
-		XLogSetRecordFlags(XLOG_INCLUDE_ORIGIN);
+		XLogSetRecordFlags(XLOG_INCLUDE_ORIGIN | XLOG_INCLUDE_XID);
 
 		(void) XLogInsert(RM_HEAP_ID, XLOG_HEAP_TRUNCATE);
 	}
diff --git a/src/backend/replication/logical/message.c b/src/backend/replication/logical/message.c
index c31dc1203f..af86d18457 100644
--- a/src/backend/replication/logical/message.c
+++ b/src/backend/replication/logical/message.c
@@ -69,7 +69,7 @@ LogLogicalMessage(const char *prefix, const char *message, size_t size,
 	XLogRegisterData(unconstify(char *, message), size);
 
 	/* allow origin filtering */
-	XLogSetRecordFlags(XLOG_INCLUDE_ORIGIN);
+	XLogSetRecordFlags(XLOG_INCLUDE_ORIGIN | XLOG_INCLUDE_XID);
 
 	return XLogInsert(RM_LOGICALMSG_ID, XLOG_LOGICAL_MESSAGE);
 }
diff --git a/src/backend/utils/cache/inval.c b/src/backend/utils/cache/inval.c
index 0008826f67..b0afdd6f90 100644
--- a/src/backend/utils/cache/inval.c
+++ b/src/backend/utils/cache/inval.c
@@ -1632,6 +1632,7 @@ LogLogicalInvalidations(void)
 		ProcessMessageSubGroupMulti(group, RelCacheMsgs,
 									XLogRegisterData((char *) msgs,
 													 n * sizeof(SharedInvalidationMessage)));
+		XLogSetRecordFlags(XLOG_INCLUDE_XID);
 		XLogInsert(RM_XACT_ID, XLOG_XACT_INVALIDATIONS);
 	}
 }
diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h
index 9007f559f3..f4dfaeda29 100644
--- a/src/include/access/xlog.h
+++ b/src/include/access/xlog.h
@@ -150,6 +150,7 @@ extern PGDLLIMPORT bool XLOG_DEBUG;
  */
 #define XLOG_INCLUDE_ORIGIN		0x01	/* include the replication origin */
 #define XLOG_MARK_UNIMPORTANT	0x02	/* record not important for durability */
+#define XLOG_INCLUDE_XID		0x04	/* include the transaction ID */
 
 
 /* Checkpoint statistics */
-- 
2.39.0