summaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>2012-06-24 18:51:37 +0300
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>2012-06-24 19:19:45 +0300
commit0ab9d1c4b31622e9176472b4276f3e9831e3d6ba (patch)
treeb8e9e5337338ba3010e00af50e1a33adb906a212 /src/include
parent061e7efb1b4c5b8a5d02122b7780531b8d5bf23d (diff)
downloadpostgresql-0ab9d1c4b31622e9176472b4276f3e9831e3d6ba.tar.gz
Replace XLogRecPtr struct with a 64-bit integer.
This simplifies code that needs to do arithmetic on XLogRecPtrs. To avoid changing on-disk format of data pages, the LSN on data pages is still stored in the old format. That should keep pg_upgrade happy. However, we have XLogRecPtrs embedded in the control file, and in the structs that are sent over the replication protocol, so this changes breaks compatibility of pg_basebackup and server. I didn't do anything about this in this patch, per discussion on -hackers, the right thing to do would to be to change the replication protocol to be architecture-independent, so that you could use a newer version of pg_receivexlog, for example, against an older server version.
Diffstat (limited to 'src/include')
-rw-r--r--src/include/access/transam.h4
-rw-r--r--src/include/access/xlog_internal.h37
-rw-r--r--src/include/access/xlogdefs.h49
-rw-r--r--src/include/catalog/pg_control.h2
-rw-r--r--src/include/storage/bufpage.h15
5 files changed, 39 insertions, 68 deletions
diff --git a/src/include/access/transam.h b/src/include/access/transam.h
index 937386575b..228f6a12c3 100644
--- a/src/include/access/transam.h
+++ b/src/include/access/transam.h
@@ -139,10 +139,6 @@ extern bool TransactionStartedDuringRecovery(void);
/* in transam/varsup.c */
extern PGDLLIMPORT VariableCache ShmemVariableCache;
-/* in transam/transam.c */
-extern const XLogRecPtr InvalidXLogRecPtr;
-
-
/*
* prototypes for functions in transam/transam.c
*/
diff --git a/src/include/access/xlog_internal.h b/src/include/access/xlog_internal.h
index d6e4bc5d7f..4ad4d13699 100644
--- a/src/include/access/xlog_internal.h
+++ b/src/include/access/xlog_internal.h
@@ -51,7 +51,7 @@ typedef struct BkpBlock
/*
* Each page of XLOG file has a header like this:
*/
-#define XLOG_PAGE_MAGIC 0xD074 /* can be used as WAL version indicator */
+#define XLOG_PAGE_MAGIC 0xD075 /* can be used as WAL version indicator */
typedef struct XLogPageHeaderData
{
@@ -113,10 +113,7 @@ typedef XLogLongPageHeaderData *XLogLongPageHeader;
#define XLogSegmentsPerXLogId (0x100000000L / XLOG_SEG_SIZE)
#define XLogSegNoOffsetToRecPtr(segno, offset, dest) \
- do { \
- (dest).xlogid = (segno) / XLogSegmentsPerXLogId; \
- (dest).xrecoff = ((segno) % XLogSegmentsPerXLogId) * XLOG_SEG_SIZE + (offset); \
- } while (0)
+ (dest) = (segno) * XLOG_SEG_SIZE + (offset)
/*
* Macros for manipulating XLOG pointers
@@ -125,8 +122,8 @@ typedef XLogLongPageHeaderData *XLogLongPageHeader;
/* Align a record pointer to next page */
#define NextLogPage(recptr) \
do { \
- if ((recptr).xrecoff % XLOG_BLCKSZ != 0) \
- XLByteAdvance(recptr, (XLOG_BLCKSZ - (recptr).xrecoff % XLOG_BLCKSZ)); \
+ if ((recptr) % XLOG_BLCKSZ != 0) \
+ XLByteAdvance(recptr, (XLOG_BLCKSZ - (recptr) % XLOG_BLCKSZ)); \
} while (0)
/*
@@ -135,14 +132,13 @@ typedef XLogLongPageHeaderData *XLogLongPageHeader;
* For XLByteToSeg, do the computation at face value. For XLByteToPrevSeg,
* a boundary byte is taken to be in the previous segment. This is suitable
* for deciding which segment to write given a pointer to a record end,
- * for example. (We can assume xrecoff is not zero, since no valid recptr
- * can have that.)
+ * for example.
*/
#define XLByteToSeg(xlrp, logSegNo) \
- logSegNo = ((uint64) (xlrp).xlogid * XLogSegmentsPerXLogId) + (xlrp).xrecoff / XLogSegSize
+ logSegNo = (xlrp) / XLogSegSize
#define XLByteToPrevSeg(xlrp, logSegNo) \
- logSegNo = ((uint64) (xlrp).xlogid * XLogSegmentsPerXLogId) + ((xlrp).xrecoff - 1) / XLogSegSize
+ logSegNo = ((xlrp) - 1) / XLogSegSize
/*
* Is an XLogRecPtr within a particular XLOG segment?
@@ -151,20 +147,15 @@ typedef XLogLongPageHeaderData *XLogLongPageHeader;
* a boundary byte is taken to be in the previous segment.
*/
#define XLByteInSeg(xlrp, logSegNo) \
- (((xlrp).xlogid) == (logSegNo) / XLogSegmentsPerXLogId && \
- ((xlrp).xrecoff / XLogSegSize) == (logSegNo) % XLogSegmentsPerXLogId)
+ (((xlrp) / XLogSegSize) == (logSegNo))
#define XLByteInPrevSeg(xlrp, logSegNo) \
- (((xlrp).xrecoff == 0) ? \
- (((xlrp).xlogid - 1) == (logSegNo) / XLogSegmentsPerXLogId && \
- ((uint32) 0xffffffff) / XLogSegSize == (logSegNo) % XLogSegmentsPerXLogId) : \
- ((xlrp).xlogid) == (logSegNo) / XLogSegmentsPerXLogId && \
- (((xlrp).xrecoff - 1) / XLogSegSize) == (logSegNo) % XLogSegmentsPerXLogId)
-
-/* Check if an xrecoff value is in a plausible range */
-#define XRecOffIsValid(xrecoff) \
- ((xrecoff) % XLOG_BLCKSZ >= SizeOfXLogShortPHD && \
- (XLOG_BLCKSZ - (xrecoff) % XLOG_BLCKSZ) >= SizeOfXLogRecord)
+ ((((xlrp) - 1) / XLogSegSize) == (logSegNo))
+
+/* Check if an XLogRecPtr value is in a plausible range */
+#define XRecOffIsValid(xlrp) \
+ ((xlrp) % XLOG_BLCKSZ >= SizeOfXLogShortPHD && \
+ (XLOG_BLCKSZ - (xlrp) % XLOG_BLCKSZ) >= SizeOfXLogRecord)
/*
* The XLog directory and control file (relative to $PGDATA)
diff --git a/src/include/access/xlogdefs.h b/src/include/access/xlogdefs.h
index 603854884f..153d0de22a 100644
--- a/src/include/access/xlogdefs.h
+++ b/src/include/access/xlogdefs.h
@@ -17,55 +17,30 @@
/*
* Pointer to a location in the XLOG. These pointers are 64 bits wide,
* because we don't want them ever to overflow.
- *
- * NOTE: xrecoff == 0 is used to indicate an invalid pointer. This is OK
- * because we use page headers in the XLOG, so no XLOG record can start
- * right at the beginning of a file.
- *
- * NOTE: the "log file number" is somewhat misnamed, since the actual files
- * making up the XLOG are much smaller than 4Gb. Each actual file is an
- * XLogSegSize-byte "segment" of a logical log file having the indicated
- * xlogid. The log file number and segment number together identify a
- * physical XLOG file. Segment number and offset within the physical file
- * are computed from xrecoff div and mod XLogSegSize.
*/
-typedef struct XLogRecPtr
-{
- uint32 xlogid; /* log file #, 0 based */
- uint32 xrecoff; /* byte offset of location in log file */
-} XLogRecPtr;
-
-#define XLogRecPtrIsInvalid(r) ((r).xrecoff == 0)
+typedef uint64 XLogRecPtr;
+/*
+ * Zero is used indicate an invalid pointer. Bootstrap skips the first possible
+ * WAL segment, initializing the first WAL page at XLOG_SEG_SIZE, so no XLOG
+ * record can begin at zero.
+ */
+#define InvalidXLogRecPtr 0
+#define XLogRecPtrIsInvalid(r) ((r) == InvalidXLogRecPtr)
/*
* Macros for comparing XLogRecPtrs
- *
- * Beware of passing expressions with side-effects to these macros,
- * since the arguments may be evaluated multiple times.
*/
-#define XLByteLT(a, b) \
- ((a).xlogid < (b).xlogid || \
- ((a).xlogid == (b).xlogid && (a).xrecoff < (b).xrecoff))
-
-#define XLByteLE(a, b) \
- ((a).xlogid < (b).xlogid || \
- ((a).xlogid == (b).xlogid && (a).xrecoff <= (b).xrecoff))
-
-#define XLByteEQ(a, b) \
- ((a).xlogid == (b).xlogid && (a).xrecoff == (b).xrecoff)
+#define XLByteLT(a, b) ((a) < (b))
+#define XLByteLE(a, b) ((a) <= (b))
+#define XLByteEQ(a, b) ((a) == (b))
/*
* Macro for advancing a record pointer by the specified number of bytes.
*/
#define XLByteAdvance(recptr, nbytes) \
- do { \
- uint32 oldxrecoff = (recptr).xrecoff; \
- (recptr).xrecoff += nbytes; \
- if ((recptr).xrecoff < oldxrecoff) \
- (recptr).xlogid += 1; /* xrecoff wrapped around */ \
- } while (0)
+ (recptr) += nbytes \
/*
* XLogSegNo - physical log file sequence number.
diff --git a/src/include/catalog/pg_control.h b/src/include/catalog/pg_control.h
index 5cff39608b..c9ee80531c 100644
--- a/src/include/catalog/pg_control.h
+++ b/src/include/catalog/pg_control.h
@@ -21,7 +21,7 @@
/* Version identifier for this pg_control format */
-#define PG_CONTROL_VERSION 922
+#define PG_CONTROL_VERSION 931
/*
* Body of CheckPoint XLOG records. This is declared here because we keep
diff --git a/src/include/storage/bufpage.h b/src/include/storage/bufpage.h
index 1ab64e021d..fc3a69b678 100644
--- a/src/include/storage/bufpage.h
+++ b/src/include/storage/bufpage.h
@@ -119,10 +119,18 @@ typedef uint16 LocationIndex;
* On the high end, we can only support pages up to 32KB because lp_off/lp_len
* are 15 bits.
*/
+
+/* for historical reasons, the LSN is stored as two 32-bit values. */
+typedef struct
+{
+ uint32 xlogid; /* high bits */
+ uint32 xrecoff; /* low bits */
+} PageXLogRecPtr;
+
typedef struct PageHeaderData
{
/* XXX LSN is member of *any* block, not only page-organized ones */
- XLogRecPtr pd_lsn; /* LSN: next byte after last byte of xlog
+ PageXLogRecPtr pd_lsn; /* LSN: next byte after last byte of xlog
* record for last change to this page */
uint16 pd_tli; /* least significant bits of the TimeLineID
* containing the LSN */
@@ -314,9 +322,10 @@ typedef PageHeaderData *PageHeader;
* Additional macros for access to page headers
*/
#define PageGetLSN(page) \
- (((PageHeader) (page))->pd_lsn)
+ ((uint64) ((PageHeader) (page))->pd_lsn.xlogid << 32 | ((PageHeader) (page))->pd_lsn.xrecoff)
#define PageSetLSN(page, lsn) \
- (((PageHeader) (page))->pd_lsn = (lsn))
+ (((PageHeader) (page))->pd_lsn.xlogid = (uint32) ((lsn) >> 32), \
+ ((PageHeader) (page))->pd_lsn.xrecoff = (uint32) (lsn))
/* NOTE: only the 16 least significant bits are stored */
#define PageGetTLI(page) \