diff --git a/postgresql-gcc-workaround.patch b/postgresql-gcc-workaround.patch new file mode 100644 index 0000000..7850821 --- /dev/null +++ b/postgresql-gcc-workaround.patch @@ -0,0 +1,111 @@ +Back-patch upstream patch to cope with a gcc 4.6.0 bug. This will be +in PG 9.0.5 and later, but we need it in Fedora *now* because the bug +breaks WAL replay, thus causing crash recovery failures as well as the +originally reported symptom of frequent reconnections during standby. + + +commit 45d792f70272ed57b932816562f31c2f79426c2a +Author: Tom Lane +Date: Fri Jun 10 17:03:11 2011 -0400 + + Work around gcc 4.6.0 bug that breaks WAL replay. + + ReadRecord's habit of using both direct references to tmpRecPtr and + references to *RecPtr (which is pointing at tmpRecPtr) triggers an + optimization bug in gcc 4.6.0, which apparently has forgotten about + aliasing rules. Avoid the compiler bug, and make the code more readable + to boot, by getting rid of the direct references. Improve the comments + while at it. + + Back-patch to all supported versions, in case they get built with 4.6.0. + + Tom Lane, with some cosmetic suggestions from Alex Hunsaker + +diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c +index bf8075d..6c18db4 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 3f0930f..367de37 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) + diff --git a/postgresql.spec b/postgresql.spec index 8ec8fc1..45e863f 100644 --- a/postgresql.spec +++ b/postgresql.spec @@ -54,7 +54,7 @@ Summary: PostgreSQL client programs Name: postgresql %global majorversion 9.0 Version: 9.0.4 -Release: 2%{?dist} +Release: 3%{?dist} # The PostgreSQL license is very similar to other MIT licenses, but the OSI # recognizes it as an independent license, so we do as well. License: PostgreSQL @@ -85,6 +85,7 @@ Source15: postgresql-bashprofile Patch1: rpm-pgsql.patch Patch2: postgresql-logging.patch Patch3: postgresql-perl-rpath.patch +Patch4: postgresql-gcc-workaround.patch BuildRequires: perl(ExtUtils::MakeMaker) glibc-devel bison flex gawk BuildRequires: perl(ExtUtils::Embed), perl-devel @@ -302,6 +303,7 @@ system, including regression tests and benchmarks. %patch1 -p1 %patch2 -p1 %patch3 -p1 +%patch4 -p1 # We used to run autoconf here, but there's no longer any real need to, # since Postgres ships with a reasonably modern configure script. @@ -820,6 +822,9 @@ rm -rf $RPM_BUILD_ROOT %endif %changelog +* Fri Jun 10 2011 Tom Lane 9.0.4-3 +- Work around gcc 4.6.0 bug (temporary backport from next upstream release) + * Tue May 10 2011 Tom Lane 9.0.4-2 - Add LSB init block to initscript, to ensure sane ordering at system boot Resolves: #703215