Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Munro2019-07-15 05:03:46 +0000
committerThomas Munro2019-07-15 05:04:29 +0000
commit67b9b3ca328392f9afc4e66fe03564f5fc87feff (patch)
tree4297fdc8925b8d36fc413e03cbce0ac79f5ca094
parent5925e5549890416bcf588334d9d0bc99f8ad6c7f (diff)
Provide XLogRecGetFullXid().
In order to be able to work with FullTransactionId values during replay without increasing the size of the WAL, infer the epoch. In general we can't do that safely, but during replay we can because we know that nextFullXid can't advance concurrently. Prevent frontend code from seeing this new function, due to the above restriction. Perhaps in future it will be possible to extract the value entirely from independent WAL records, and then this restriction can be lifted. Author: Thomas Munro, based on earlier code from Andres Freund Discussion: https://postgr.es/m/CA%2BhUKG%2BmLmuDjMi6o1dxkKvGRL56Y2Rz%2BiXAcrZV03G9ZuFQ8Q%40mail.gmail.com
-rw-r--r--src/backend/access/transam/xlogreader.c35
-rw-r--r--src/include/access/xlogreader.h8
2 files changed, 43 insertions, 0 deletions
diff --git a/src/backend/access/transam/xlogreader.c b/src/backend/access/transam/xlogreader.c
index 41dae916b46..33ccfc15531 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 04228e2a871..a12c94cba67 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,