commit 0114c5ed160a94e35e35c5c018360ff48ee15771
Author: Heikki Linnakangas <heikki.linnakangas@iki.fi>
Date:   Wed Jun 6 13:11:56 2012 +0300

    Move continuation record field xl_rem_len to xlog page header.

diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index fddfbc4..6935149 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -693,7 +693,6 @@ XLogInsert(RmgrId rmid, uint8 info, XLogRecData *rdata)
 {
 	XLogCtlInsert *Insert = &XLogCtl->Insert;
 	XLogRecord *record;
-	XLogContRecord *contrecord;
 	XLogRecPtr	RecPtr;
 	XLogRecPtr	WriteRqst;
 	uint32		freespace;
@@ -1082,9 +1081,7 @@ begin:;
 		curridx = Insert->curridx;
 		/* Insert cont-record header */
 		Insert->currpage->xlp_info |= XLP_FIRST_IS_CONTRECORD;
-		contrecord = (XLogContRecord *) Insert->currpos;
-		contrecord->xl_rem_len = write_len;
-		Insert->currpos += SizeOfXLogContRecord;
+		Insert->currpage->xlp_rem_len = write_len;
 		freespace = INSERT_FREESPACE(Insert);
 	}
 
@@ -3930,7 +3927,8 @@ retry:
 	if (total_len > len)
 	{
 		/* Need to reassemble record */
-		XLogContRecord *contrecord;
+		char	   *contrecord;
+		XLogPageHeader pageHeader;
 		XLogRecPtr	pagelsn;
 		uint32		gotlen = len;
 
@@ -3958,30 +3956,30 @@ retry:
 								readOff)));
 				goto next_record_is_invalid;
 			}
-			pageHeaderSize = XLogPageHeaderSize((XLogPageHeader) readBuf);
-			contrecord = (XLogContRecord *) ((char *) readBuf + pageHeaderSize);
-			if (contrecord->xl_rem_len == 0 ||
-				total_len != (contrecord->xl_rem_len + gotlen))
+			pageHeader = (XLogPageHeader) readBuf;
+			pageHeaderSize = XLogPageHeaderSize(pageHeader);
+			contrecord = (char *) readBuf + pageHeaderSize;
+			if (pageHeader->xlp_rem_len == 0 ||
+				total_len != (pageHeader->xlp_rem_len + gotlen))
 			{
 				char fname[MAXFNAMELEN];
 				XLogFileName(fname, curFileTLI, readSegNo);
 				ereport(emode_for_corrupt_record(emode, *RecPtr),
 						(errmsg("invalid contrecord length %u in log segment %s, offset %u",
-								contrecord->xl_rem_len,
+								pageHeader->xlp_rem_len,
 								XLogFileNameP(curFileTLI, readSegNo),
 								readOff)));
 				goto next_record_is_invalid;
 			}
-			len = XLOG_BLCKSZ - pageHeaderSize - SizeOfXLogContRecord;
-			if (contrecord->xl_rem_len > len)
+			len = XLOG_BLCKSZ - pageHeaderSize;
+			if (pageHeader->xlp_rem_len > len)
 			{
-				memcpy(buffer, (char *) contrecord + SizeOfXLogContRecord, len);
+				memcpy(buffer, (char *) contrecord, len);
 				gotlen += len;
 				buffer += len;
 				continue;
 			}
-			memcpy(buffer, (char *) contrecord + SizeOfXLogContRecord,
-				   contrecord->xl_rem_len);
+			memcpy(buffer, (char *) contrecord, pageHeader->xlp_rem_len);
 			break;
 		}
 		if (!RecordIsValid(record, *RecPtr, emode))
@@ -3989,8 +3987,7 @@ retry:
 		pageHeaderSize = XLogPageHeaderSize((XLogPageHeader) readBuf);
 		XLogSegNoOffsetToRecPtr(
 			readSegNo,
-			readOff + pageHeaderSize +
-				MAXALIGN(SizeOfXLogContRecord + contrecord->xl_rem_len),
+			readOff + pageHeaderSize + MAXALIGN(pageHeader->xlp_rem_len),
 			EndRecPtr);
 		ReadRecPtr = *RecPtr;
 		/* needn't worry about XLOG SWITCH, it can't cross page boundaries */
diff --git a/src/include/access/xlog_internal.h b/src/include/access/xlog_internal.h
index e1d4bc8..239b749 100644
--- a/src/include/access/xlog_internal.h
+++ b/src/include/access/xlog_internal.h
@@ -49,26 +49,6 @@ typedef struct BkpBlock
 } BkpBlock;
 
 /*
- * When there is not enough space on current page for whole record, we
- * continue on the next page with continuation record.	(However, the
- * XLogRecord header will never be split across pages; if there's less than
- * SizeOfXLogRecord space left at the end of a page, we just waste it.)
- *
- * Note that xl_rem_len includes backup-block data; that is, it tracks
- * xl_tot_len not xl_len in the initial header.  Also note that the
- * continuation data isn't necessarily aligned.
- */
-typedef struct XLogContRecord
-{
-	uint32		xl_rem_len;		/* total len of remaining data for record */
-
-	/* ACTUAL LOG DATA FOLLOWS AT END OF STRUCT */
-
-} XLogContRecord;
-
-#define SizeOfXLogContRecord	sizeof(XLogContRecord)
-
-/*
  * Each page of XLOG file has a header like this:
  */
 #define XLOG_PAGE_MAGIC 0xD071	/* can be used as WAL version indicator */
@@ -79,6 +59,19 @@ typedef struct XLogPageHeaderData
 	uint16		xlp_info;		/* flag bits, see below */
 	TimeLineID	xlp_tli;		/* TimeLineID of first record on page */
 	XLogRecPtr	xlp_pageaddr;	/* XLOG address of this page */
+
+	/*
+	 * When there is not enough space on current page for whole record, we
+	 * continue on the next page.  xlp_rem_len is the number of bytes
+	 * remaining from a previous page. (However, the XLogRecord header will
+	 * never be split across pages; if there's less than SizeOfXLogRecord
+	 * space left at the end of a page, we just waste it.)
+	 *
+	 * Note that xl_rem_len includes backup-block data; that is, it tracks
+	 * xl_tot_len not xl_len in the initial header.  Also note that the
+	 * continuation data isn't necessarily aligned.
+	 */
+	uint32		xlp_rem_len;	/* total len of remaining data for record */
 } XLogPageHeaderData;
 
 #define SizeOfXLogShortPHD	MAXALIGN(sizeof(XLogPageHeaderData))
