From 501ace5f11cb90101b3a770de3ada9f541af698c Mon Sep 17 00:00:00 2001 From: Matthias van de Meent 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