aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>2010-11-02 11:23:43 +0200
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>2010-11-02 11:39:48 +0200
commit8c843fff2d8db7889b81782ab4f3324cbda4ed2a (patch)
tree4e077881b96aed36906cc344521344817b5f941a /src
parent0811ff2063be973953eda89e76dac0d299f0fb6b (diff)
downloadpostgresql-8c843fff2d8db7889b81782ab4f3324cbda4ed2a.tar.gz
postgresql-8c843fff2d8db7889b81782ab4f3324cbda4ed2a.zip
Bootstrap WAL to begin at segment logid=0 logseg=1 (000000010000000000000001)
rather than 0/0, so that we can safely use 0/0 as an invalid value. This is a more future-proof fix for the corner-case bug in streaming replication that was fixed yesterday. We had a similar corner-case bug with log/seg 0/0 back in February as well. Avoiding 0/0 as a valid value should prevent bugs like that in the future. Per Tom Lane's idea. Back-patch to 9.0. Since this only affects bootstrapping, it makes no difference to existing installations. We don't need to worry about the bug in existing installations, because if you've managed to get past the initial base backup already, you won't hit the bug in the future either.
Diffstat (limited to 'src')
-rw-r--r--src/backend/access/transam/xlog.c21
-rw-r--r--src/backend/replication/walsender.c2
2 files changed, 13 insertions, 10 deletions
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 97dced113a9..786d0c696d1 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -364,7 +364,7 @@ typedef struct XLogCtlData
uint32 ckptXidEpoch; /* nextXID & epoch of latest checkpoint */
TransactionId ckptXid;
XLogRecPtr asyncXactLSN; /* LSN of newest async commit/abort */
- uint32 lastRemovedLog; /* latest removed/recycled XLOG segment + 1 */
+ uint32 lastRemovedLog; /* latest removed/recycled XLOG segment */
uint32 lastRemovedSeg;
/* Protected by WALWriteLock: */
@@ -3218,9 +3218,7 @@ PreallocXlogFiles(XLogRecPtr endptr)
}
/*
- * Get the log/seg of the first WAL segment that has not been removed or
- * recycled. In other words, the log/seg of the last removed/recycled WAL
- * segment + 1.
+ * Get the log/seg of the latest removed or recycled WAL segment.
* Returns 0/0 if no WAL segments have been removed since startup.
*/
void
@@ -3249,7 +3247,6 @@ UpdateLastRemovedPtr(char *filename)
seg;
XLogFromFileName(filename, &tli, &log, &seg);
- NextLogSeg(log, seg);
SpinLockAcquire(&xlogctl->info_lck);
if (log > xlogctl->lastRemovedLog ||
@@ -4903,9 +4900,15 @@ BootStrapXLOG(void)
page = (XLogPageHeader) TYPEALIGN(ALIGNOF_XLOG_BUFFER, buffer);
memset(page, 0, XLOG_BLCKSZ);
- /* Set up information for the initial checkpoint record */
+ /*
+ * Set up information for the initial checkpoint record
+ *
+ * The initial checkpoint record is written to the beginning of the
+ * WAL segment with logid=0 logseg=1. The very first WAL segment, 0/0, is
+ * not used, so that we can use 0/0 to mean "before any valid WAL segment".
+ */
checkPoint.redo.xlogid = 0;
- checkPoint.redo.xrecoff = SizeOfXLogLongPHD;
+ checkPoint.redo.xrecoff = XLogSegSize + SizeOfXLogLongPHD;
checkPoint.ThisTimeLineID = ThisTimeLineID;
checkPoint.nextXidEpoch = 0;
checkPoint.nextXid = FirstNormalTransactionId;
@@ -4928,7 +4931,7 @@ BootStrapXLOG(void)
page->xlp_info = XLP_LONG_HEADER;
page->xlp_tli = ThisTimeLineID;
page->xlp_pageaddr.xlogid = 0;
- page->xlp_pageaddr.xrecoff = 0;
+ page->xlp_pageaddr.xrecoff = XLogSegSize;
longpage = (XLogLongPageHeader) page;
longpage->xlp_sysid = sysidentifier;
longpage->xlp_seg_size = XLogSegSize;
@@ -4954,7 +4957,7 @@ BootStrapXLOG(void)
/* Create first XLOG segment file */
use_existent = false;
- openLogFile = XLogFileInit(0, 0, &use_existent, false);
+ openLogFile = XLogFileInit(0, 1, &use_existent, false);
/* Write the first page with the initial record */
errno = 0;
diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index 3dc794ccc9c..d2b9e5c5f9a 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -654,7 +654,7 @@ XLogRead(char *buf, XLogRecPtr recptr, Size nbytes)
XLogGetLastRemoved(&lastRemovedLog, &lastRemovedSeg);
XLByteToSeg(startRecPtr, log, seg);
if (log < lastRemovedLog ||
- (log == lastRemovedLog && seg < lastRemovedSeg))
+ (log == lastRemovedLog && seg <= lastRemovedSeg))
{
char filename[MAXFNAMELEN];