diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/backend/access/transam/xlog.c | 37 | ||||
| -rw-r--r-- | src/include/access/xlog_internal.h | 12 | 
2 files changed, 30 insertions, 19 deletions
| diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index bf8075d2ec3..6c18db4050f 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -3676,23 +3676,32 @@ ReadRecord(XLogRecPtr *RecPtr, int emode, bool fetching_ckpt)  		RecPtr = &tmpRecPtr;  		/* -		 * Align recptr to next page if no more records can fit on the current -		 * page. +		 * RecPtr is pointing to end+1 of the previous WAL record.  We must +		 * advance it if necessary to where the next record starts.  First, +		 * align to next page if no more records can fit on the current page.  		 */  		if (XLOG_BLCKSZ - (RecPtr->xrecoff % XLOG_BLCKSZ) < SizeOfXLogRecord) -		{ -			NextLogPage(tmpRecPtr); -			/* We will account for page header size below */ -		} +			NextLogPage(*RecPtr); -		if (tmpRecPtr.xrecoff >= XLogFileSize) +		/* Check for crossing of xlog segment boundary */ +		if (RecPtr->xrecoff >= XLogFileSize)  		{ -			(tmpRecPtr.xlogid)++; -			tmpRecPtr.xrecoff = 0; +			(RecPtr->xlogid)++; +			RecPtr->xrecoff = 0;  		} + +		/* +		 * If at page start, we must skip over the page header.  But we can't +		 * do that until we've read in the page, since the header size is +		 * variable. +		 */  	}  	else  	{ +		/* +		 * In this case, the passed-in record pointer should already be +		 * pointing to a valid record starting position. +		 */  		if (!XRecOffIsValid(RecPtr->xrecoff))  			ereport(PANIC,  					(errmsg("invalid record offset at %X/%X", @@ -3721,11 +3730,13 @@ retry:  	if (targetRecOff == 0)  	{  		/* -		 * Can only get here in the continuing-from-prev-page case, because -		 * XRecOffIsValid eliminated the zero-page-offset case otherwise. Need -		 * to skip over the new page's header. +		 * At page start, so skip over page header.  The Assert checks that +		 * we're not scribbling on caller's record pointer; it's OK because we +		 * can only get here in the continuing-from-prev-record case, since +		 * XRecOffIsValid rejected the zero-page-offset case otherwise.  		 */ -		tmpRecPtr.xrecoff += pageHeaderSize; +		Assert(RecPtr == &tmpRecPtr); +		RecPtr->xrecoff += pageHeaderSize;  		targetRecOff = pageHeaderSize;  	}  	else if (targetRecOff < pageHeaderSize) diff --git a/src/include/access/xlog_internal.h b/src/include/access/xlog_internal.h index 3f0930f3951..367de374ead 100644 --- a/src/include/access/xlog_internal.h +++ b/src/include/access/xlog_internal.h @@ -154,13 +154,13 @@ typedef XLogLongPageHeaderData *XLogLongPageHeader;  /* Align a record pointer to next page */  #define NextLogPage(recptr) \  	do {	\ -		if (recptr.xrecoff % XLOG_BLCKSZ != 0)	\ -			recptr.xrecoff +=	\ -				(XLOG_BLCKSZ - recptr.xrecoff % XLOG_BLCKSZ);	\ -		if (recptr.xrecoff >= XLogFileSize) \ +		if ((recptr).xrecoff % XLOG_BLCKSZ != 0)	\ +			(recptr).xrecoff +=	\ +				(XLOG_BLCKSZ - (recptr).xrecoff % XLOG_BLCKSZ);	\ +		if ((recptr).xrecoff >= XLogFileSize) \  		{	\ -			(recptr.xlogid)++;	\ -			recptr.xrecoff = 0; \ +			((recptr).xlogid)++;	\ +			(recptr).xrecoff = 0; \  		}	\  	} while (0) | 
