From b8054982cee3e51db593c9e446cceb6788d7ab13 Mon Sep 17 00:00:00 2001 From: Maxim Orlov Date: Fri, 29 Dec 2023 14:42:13 +0300 Subject: [PATCH v1 2/2] Switch to FullTransactionId for XLogRecord->xl_xid As a step towards 64bit xids switch to FullTransactionId for XLogRecord->xl_xid. Author: Maxim Orlov --- src/backend/access/transam/xlog.c | 2 +- src/backend/access/transam/xloginsert.c | 2 +- src/backend/access/transam/xlogreader.c | 17 +--------------- src/backend/access/transam/xlogrecovery.c | 6 +++--- src/bin/pg_resetwal/pg_resetwal.c | 2 +- src/bin/pg_waldump/pg_waldump.c | 2 +- src/include/access/xlogreader.h | 2 +- src/include/access/xlogrecord.h | 9 +++++---- src/test/recovery/t/039_end_of_wal.pl | 24 +++++++++++++---------- 9 files changed, 28 insertions(+), 38 deletions(-) diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 1264849883..c38a39beda 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -4906,7 +4906,7 @@ BootStrapXLOG(void) recptr = ((char *) page + SizeOfXLogLongPHD); record = (XLogRecord *) recptr; record->xl_prev = 0; - record->xl_xid = InvalidTransactionId; + record->xl_xid = InvalidFullTransactionId; record->xl_tot_len = SizeOfXLogRecord + SizeOfXLogRecordDataHeaderShort + sizeof(checkPoint); record->xl_info = XLOG_CHECKPOINT_SHUTDOWN; record->xl_rmid = RM_XLOG_ID; diff --git a/src/backend/access/transam/xloginsert.c b/src/backend/access/transam/xloginsert.c index e4aaa551a0..8c25e43fb7 100644 --- a/src/backend/access/transam/xloginsert.c +++ b/src/backend/access/transam/xloginsert.c @@ -924,7 +924,7 @@ XLogRecordAssemble(RmgrId rmid, uint8 info, * 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(); + rechdr->xl_xid = GetCurrentFullTransactionIdIfAny(); rechdr->xl_tot_len = (uint32) total_len; rechdr->xl_info = info; rechdr->xl_rmid = rmid; diff --git a/src/backend/access/transam/xlogreader.c b/src/backend/access/transam/xlogreader.c index 6b404b8169..e1251c8638 100644 --- a/src/backend/access/transam/xlogreader.c +++ b/src/backend/access/transam/xlogreader.c @@ -2171,28 +2171,13 @@ RestoreBlockImage(XLogReaderState *record, uint8 block_id, char *page) FullTransactionId XLogRecGetFullXid(XLogReaderState *record) { - TransactionId xid, - next_xid; - uint32 epoch; - /* * This function is only safe during replay, because it depends on the * replay state. See AdvanceNextFullTransactionIdPastXid() for more. */ Assert(AmStartupProcess() || !IsUnderPostmaster); - xid = XLogRecGetXid(record); - next_xid = XidFromFullTransactionId(TransamVariables->nextXid); - epoch = EpochFromFullTransactionId(TransamVariables->nextXid); - - /* - * If xid is numerically greater than next_xid, it has to be from the last - * epoch. - */ - if (unlikely(xid > next_xid)) - --epoch; - - return FullTransactionIdFromEpochAndXid(epoch, xid); + return record->record->header.xl_xid; } #endif diff --git a/src/backend/access/transam/xlogrecovery.c b/src/backend/access/transam/xlogrecovery.c index 6f4f81f992..dd3d770c3a 100644 --- a/src/backend/access/transam/xlogrecovery.c +++ b/src/backend/access/transam/xlogrecovery.c @@ -1875,7 +1875,7 @@ ApplyWalRecord(XLogReaderState *xlogreader, XLogRecord *record, TimeLineID *repl /* * TransamVariables->nextXid must be beyond record's xid. */ - AdvanceNextFullTransactionIdPastXid(record->xl_xid); + AdvanceNextFullTransactionIdPastXid(XidFromFullTransactionId(record->xl_xid)); /* * Before replaying this record, check if this record causes the current @@ -1933,8 +1933,8 @@ ApplyWalRecord(XLogReaderState *xlogreader, XLogRecord *record, TimeLineID *repl * If we are attempting to enter Hot Standby mode, process XIDs we see */ if (standbyState >= STANDBY_INITIALIZED && - TransactionIdIsValid(record->xl_xid)) - RecordKnownAssignedTransactionIds(record->xl_xid); + FullTransactionIdIsValid(record->xl_xid)) + RecordKnownAssignedTransactionIds(XidFromFullTransactionId(record->xl_xid)); /* * Some XLOG record types that are related to recovery are processed diff --git a/src/bin/pg_resetwal/pg_resetwal.c b/src/bin/pg_resetwal/pg_resetwal.c index 5407f51a4e..43eb22d415 100644 --- a/src/bin/pg_resetwal/pg_resetwal.c +++ b/src/bin/pg_resetwal/pg_resetwal.c @@ -1105,7 +1105,7 @@ WriteEmptyXLOG(void) recptr = (char *) page + SizeOfXLogLongPHD; record = (XLogRecord *) recptr; record->xl_prev = 0; - record->xl_xid = InvalidTransactionId; + record->xl_xid = InvalidFullTransactionId; record->xl_tot_len = SizeOfXLogRecord + SizeOfXLogRecordDataHeaderShort + sizeof(CheckPoint); record->xl_info = XLOG_CHECKPOINT_SHUTDOWN; record->xl_rmid = RM_XLOG_ID; diff --git a/src/bin/pg_waldump/pg_waldump.c b/src/bin/pg_waldump/pg_waldump.c index a3535bdfa9..7200166282 100644 --- a/src/bin/pg_waldump/pg_waldump.c +++ b/src/bin/pg_waldump/pg_waldump.c @@ -1261,7 +1261,7 @@ main(int argc, char **argv) continue; if (config.filter_by_xid_enabled && - config.filter_by_xid != record->xl_xid) + config.filter_by_xid != XidFromFullTransactionId(record->xl_xid)) continue; /* check for extended filtering */ diff --git a/src/include/access/xlogreader.h b/src/include/access/xlogreader.h index 0813722715..0de1cffd4f 100644 --- a/src/include/access/xlogreader.h +++ b/src/include/access/xlogreader.h @@ -409,7 +409,7 @@ extern bool DecodeXLogRecord(XLogReaderState *state, #define XLogRecGetPrev(decoder) ((decoder)->record->header.xl_prev) #define XLogRecGetInfo(decoder) ((decoder)->record->header.xl_info) #define XLogRecGetRmid(decoder) ((decoder)->record->header.xl_rmid) -#define XLogRecGetXid(decoder) ((decoder)->record->header.xl_xid) +#define XLogRecGetXid(decoder) ((uint32) ((decoder)->record->header.xl_xid.value)) #define XLogRecGetOrigin(decoder) ((decoder)->record->record_origin) #define XLogRecGetTopXid(decoder) ((decoder)->record->toplevel_xid) #define XLogRecGetData(decoder) ((decoder)->record->main_data) diff --git a/src/include/access/xlogrecord.h b/src/include/access/xlogrecord.h index ec9a3c802a..99157af92a 100644 --- a/src/include/access/xlogrecord.h +++ b/src/include/access/xlogrecord.h @@ -12,6 +12,7 @@ #define XLOGRECORD_H #include "access/rmgr.h" +#include "access/transam.h" #include "access/xlogdefs.h" #include "port/pg_crc32c.h" #include "storage/block.h" @@ -41,18 +42,18 @@ typedef struct XLogRecord { uint32 xl_tot_len; /* total len of entire record */ - TransactionId xl_xid; /* xact id */ + pg_crc32c xl_crc; /* CRC for this record */ + FullTransactionId xl_xid; /* xact id */ XLogRecPtr xl_prev; /* ptr to previous record in log */ uint8 xl_info; /* flag bits, see below */ RmgrId xl_rmid; /* resource manager for this record */ - /* 2 bytes of padding here, initialize to zero */ - pg_crc32c xl_crc; /* CRC for this record */ + /* 6 bytes of padding here, initialize to zero */ /* XLogRecordBlockHeaders and XLogRecordDataHeader follow, no padding */ } XLogRecord; -#define SizeOfXLogRecord (offsetof(XLogRecord, xl_crc) + sizeof(pg_crc32c)) +#define SizeOfXLogRecord (offsetof(XLogRecord, xl_rmid) + sizeof(RmgrId)) /* * The high 4 bits in xl_info may be used freely by rmgr. The diff --git a/src/test/recovery/t/039_end_of_wal.pl b/src/test/recovery/t/039_end_of_wal.pl index d2bf062bb2..d4aca99995 100644 --- a/src/test/recovery/t/039_end_of_wal.pl +++ b/src/test/recovery/t/039_end_of_wal.pl @@ -21,7 +21,7 @@ use integer; # causes / operator to use integer math my $BIG_ENDIAN = pack("L", 0x12345678) eq pack("N", 0x12345678); # Header size of record header. -my $RECORD_HEADER_SIZE = 24; +my $RECORD_HEADER_SIZE = 26; # Fields retrieved from code headers. my @scan_result = scan_server_header('access/xlog_internal.h', @@ -131,17 +131,21 @@ sub build_record_header # This needs to follow the structure XLogRecord: # I for xl_tot_len - # I for xl_xid + # I for xl_crc + # II for xl_xid # II for xl_prev # C for xl_info # C for xl_rmid - # BB for two bytes of padding - # I for xl_crc - return pack("IIIICCBBI", - $xl_tot_len, $xl_xid, + # BBBBBB for two bytes of padding + return pack("IIIIIICCBBBBBB", + $xl_tot_len, + $xl_crc, + $BIG_ENDIAN ? 0 : $xl_xid, + $BIG_ENDIAN ? $xl_xid : 0, $BIG_ENDIAN ? 0 : $xl_prev, $BIG_ENDIAN ? $xl_prev : 0, - $xl_info, $xl_rmid, 0, 0, $xl_crc); + $xl_info, $xl_rmid, + 0, 0, 0, 0, 0, 0); } # Build a fake WAL page header, based on the data given by the caller @@ -265,7 +269,7 @@ $node->stop('immediate'); my $log_size = -s $node->logfile; $node->start; ok( $node->log_contains( - "invalid record length at .*: expected at least 24, got 0", $log_size + "invalid record length at .*: expected at least 26, got 0", $log_size ), "xl_tot_len zero"); @@ -277,7 +281,7 @@ write_wal($node, $TLI, $end_lsn, build_record_header(23)); $log_size = -s $node->logfile; $node->start; ok( $node->log_contains( - "invalid record length at .*: expected at least 24, got 23", + "invalid record length at .*: expected at least 26, got 23", $log_size), "xl_tot_len short"); @@ -290,7 +294,7 @@ write_wal($node, $TLI, $end_lsn, build_record_header(1)); $log_size = -s $node->logfile; $node->start; ok( $node->log_contains( - "invalid record length at .*: expected at least 24, got 1", $log_size + "invalid record length at .*: expected at least 26, got 1", $log_size ), "xl_tot_len short at end-of-page"); -- 2.42.0