Commit 061e7efb authored by Heikki Linnakangas's avatar Heikki Linnakangas

Allow WAL record header to be split across pages.

This saves a few bytes of WAL space, but the real motivation is to make it
predictable how much WAL space a record requires, as it no longer depends
on whether we need to waste the last few bytes at end of WAL page because
the header doesn't fit.

The total length field of WAL record, xl_tot_len, is moved to the beginning
of the WAL record header, so that it is still always found on the first page
where a WAL record begins.

Bump WAL version number again as this is an incompatible change.
parent 20ba5ca6
This diff is collapsed.
...@@ -942,8 +942,7 @@ WriteEmptyXLOG(void) ...@@ -942,8 +942,7 @@ WriteEmptyXLOG(void)
INIT_CRC32(crc); INIT_CRC32(crc);
COMP_CRC32(crc, &ControlFile.checkPointCopy, sizeof(CheckPoint)); COMP_CRC32(crc, &ControlFile.checkPointCopy, sizeof(CheckPoint));
COMP_CRC32(crc, (char *) record + sizeof(pg_crc32), COMP_CRC32(crc, (char *) record, offsetof(XLogRecord, xl_crc));
SizeOfXLogRecord - sizeof(pg_crc32));
FIN_CRC32(crc); FIN_CRC32(crc);
record->xl_crc = crc; record->xl_crc = crc;
......
...@@ -40,15 +40,16 @@ ...@@ -40,15 +40,16 @@
*/ */
typedef struct XLogRecord typedef struct XLogRecord
{ {
pg_crc32 xl_crc; /* CRC for this record */
XLogRecPtr xl_prev; /* ptr to previous record in log */
TransactionId xl_xid; /* xact id */
uint32 xl_tot_len; /* total len of entire record */ uint32 xl_tot_len; /* total len of entire record */
TransactionId xl_xid; /* xact id */
uint32 xl_len; /* total len of rmgr data */ uint32 xl_len; /* total len of rmgr data */
uint8 xl_info; /* flag bits, see below */ uint8 xl_info; /* flag bits, see below */
RmgrId xl_rmid; /* resource manager for this record */ RmgrId xl_rmid; /* resource manager for this record */
/* 2 bytes of padding here, initialize to zero */
XLogRecPtr xl_prev; /* ptr to previous record in log */
pg_crc32 xl_crc; /* CRC for this record */
/* Depending on MAXALIGN, there are either 2 or 6 wasted bytes here */ /* If MAXALIGN==8, there are 4 wasted bytes here */
/* ACTUAL LOG DATA FOLLOWS AT END OF STRUCT */ /* ACTUAL LOG DATA FOLLOWS AT END OF STRUCT */
......
...@@ -51,7 +51,7 @@ typedef struct BkpBlock ...@@ -51,7 +51,7 @@ typedef struct BkpBlock
/* /*
* Each page of XLOG file has a header like this: * Each page of XLOG file has a header like this:
*/ */
#define XLOG_PAGE_MAGIC 0xD073 /* can be used as WAL version indicator */ #define XLOG_PAGE_MAGIC 0xD074 /* can be used as WAL version indicator */
typedef struct XLogPageHeaderData typedef struct XLogPageHeaderData
{ {
...@@ -63,9 +63,7 @@ typedef struct XLogPageHeaderData ...@@ -63,9 +63,7 @@ typedef struct XLogPageHeaderData
/* /*
* When there is not enough space on current page for whole record, we * 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 * continue on the next page. xlp_rem_len is the number of bytes
* remaining from a previous page. (However, the XLogRecord header will * remaining from a previous page.
* 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 * 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 * xl_tot_len not xl_len in the initial header. Also note that the
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment