On Fri, Jun 10, 2011 at 12:38, Tom Lane <[email protected]> wrote:
>
> I've been able to reproduce this on released Fedora 15, and sure enough
> it is a compiler bug. The problem comes from these fragments of
> ReadRecord():
> [ ... ]
Whoa, awesome. I spent a few more hours comparing the assembly-- then
I tried compiling a subset of xlog.c with some educated guesses as to
what function might be getting mis-compiled. Obviously my guesses were
not educated enough! :-)
> I've filed a bug report for this:
> https://bugzilla.redhat.com/show_bug.cgi?id=712480
> but I wouldn't care to hold my breath while waiting for a fix to appear
> upstream, let alone propagate to all the distros already using 4.6.0.
I wouldn't hold my breath either.
> I think we need a workaround.
>
> The obvious question to ask here is why are we updating
> "tmpRecPtr.xrecoff" and not "RecPtr->xrecoff"? The latter choice would
> be a lot more readable, since the immediately surrounding code doesn't
> refer to tmpRecPtr. I think the idea is to guarantee that the caller's
> referenced record pointer (if any) isn't modified, but if RecPtr is not
> pointing at tmpRecPtr here, we have got big problems anyway.
Hrm, Couldn't we change all the references to tmpRecPtr to use RecPtr
instead? (Except of course where we assign RecPtr = &tmpRecPtr); I
think that would make the code look a lot less confused. Something
like the attached?
FYI Im happy to test whatever you fix you propose for a few days on
this machine. It gets a fair amount of traffic... hopefully enough to
exercise some possible corner cases.
*** a/src/backend/access/transam/xlog.c
--- b/src/backend/access/transam/xlog.c
***************
*** 3681,3694 **** ReadRecord(XLogRecPtr *RecPtr, int emode, bool fetching_ckpt)
*/
if (XLOG_BLCKSZ - (RecPtr->xrecoff % XLOG_BLCKSZ) < SizeOfXLogRecord)
{
! NextLogPage(tmpRecPtr);
/* We will account for page header size below */
}
! if (tmpRecPtr.xrecoff >= XLogFileSize)
{
! (tmpRecPtr.xlogid)++;
! tmpRecPtr.xrecoff = 0;
}
}
else
--- 3681,3694 ----
*/
if (XLOG_BLCKSZ - (RecPtr->xrecoff % XLOG_BLCKSZ) < SizeOfXLogRecord)
{
! NextLogPage(RecPtr);
/* We will account for page header size below */
}
! if (RecPtr->xrecoff >= XLogFileSize)
{
! (RecPtr->xlogid)++;
! RecPtr->xrecoff = 0;
}
}
else
***************
*** 3725,3731 **** retry:
* XRecOffIsValid eliminated the zero-page-offset case otherwise. Need
* to skip over the new page's header.
*/
! tmpRecPtr.xrecoff += pageHeaderSize;
targetRecOff = pageHeaderSize;
}
else if (targetRecOff < pageHeaderSize)
--- 3725,3731 ----
* XRecOffIsValid eliminated the zero-page-offset case otherwise. Need
* to skip over the new page's header.
*/
! RecPtr->xrecoff += pageHeaderSize;
targetRecOff = pageHeaderSize;
}
else if (targetRecOff < pageHeaderSize)
*** a/src/include/access/xlog_internal.h
--- b/src/include/access/xlog_internal.h
***************
*** 154,166 **** 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) \
{ \
! (recptr.xlogid)++; \
! recptr.xrecoff = 0; \
} \
} while (0)
--- 154,166 ----
/* 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) \
{ \
! (recptr->xlogid)++; \
! recptr->xrecoff = 0; \
} \
} while (0)
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers