diff --git a/src/backend/access/transam/xlogreader.c b/src/backend/access/transam/xlogreader.c index 41dae916b4..33ccfc1553 100644 --- a/src/backend/access/transam/xlogreader.c +++ b/src/backend/access/transam/xlogreader.c @@ -26,6 +26,7 @@ #include "replication/origin.h" #ifndef FRONTEND +#include "miscadmin.h" #include "utils/memutils.h" #endif @@ -1443,3 +1444,37 @@ RestoreBlockImage(XLogReaderState *record, uint8 block_id, char *page) return true; } + +#ifndef FRONTEND + +/* + * Extract the FullTransactionId from a WAL record. + */ +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(ShmemVariableCache->nextFullXid); + epoch = EpochFromFullTransactionId(ShmemVariableCache->nextFullXid); + + /* + * 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); +}; + +#endif diff --git a/src/include/access/xlogreader.h b/src/include/access/xlogreader.h index 04228e2a87..a12c94cba6 100644 --- a/src/include/access/xlogreader.h +++ b/src/include/access/xlogreader.h @@ -25,6 +25,10 @@ #ifndef XLOGREADER_H #define XLOGREADER_H +#ifndef FRONTEND +#include "access/transam.h" +#endif + #include "access/xlogrecord.h" typedef struct XLogReaderState XLogReaderState; @@ -240,6 +244,10 @@ extern bool DecodeXLogRecord(XLogReaderState *state, XLogRecord *record, #define XLogRecBlockImageApply(decoder, block_id) \ ((decoder)->blocks[block_id].apply_image) +#ifndef FRONTEND +extern FullTransactionId XLogRecGetFullXid(XLogReaderState *record); +#endif + extern bool RestoreBlockImage(XLogReaderState *recoder, uint8 block_id, char *dst); extern char *XLogRecGetBlockData(XLogReaderState *record, uint8 block_id, Size *len); extern bool XLogRecGetBlockTag(XLogReaderState *record, uint8 block_id,