2-move-continuation-record-to-page-header.patch
text/x-diff
Filename: 2-move-continuation-record-to-page-header.patch
Type: text/x-diff
Part: 1
Message:
WAL format changes
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
| File | + | − |
|---|---|---|
| src/backend/access/transam/xlog.c | 14 | 17 |
| src/include/access/xlog_internal.h | 13 | 20 |
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))