diff options
author | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2010-11-01 09:56:45 +0200 |
---|---|---|
committer | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2010-11-01 10:05:15 +0200 |
commit | 931b6db39b808608a3c80c42b47e3cbcda9e66db (patch) | |
tree | 85df99562f5b7178a03ca7c72d095180e7d7777a /src | |
parent | 76b12e0af765b2ca2eeddcabdd5e7c22eda164da (diff) | |
download | postgresql-931b6db39b808608a3c80c42b47e3cbcda9e66db.tar.gz postgresql-931b6db39b808608a3c80c42b47e3cbcda9e66db.zip |
Fix corner-case bug in tracking of latest removed WAL segment during
streaming replication. We used log/seg 0/0 to indicate that no WAL segments
have been removed since startup, but 0/0 is a valid value for the very first
WAL segment after initdb. To make that disambiguous, store
(latest removed WAL segment + 1) in the global variable.
Per report from Matt Chesler, also reproduced by Greg Smith.
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/access/transam/xlog.c | 9 | ||||
-rw-r--r-- | src/backend/replication/walsender.c | 2 |
2 files changed, 7 insertions, 4 deletions
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 6f1fedd1140..97dced113a9 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 */ + uint32 lastRemovedLog; /* latest removed/recycled XLOG segment + 1 */ uint32 lastRemovedSeg; /* Protected by WALWriteLock: */ @@ -3218,8 +3218,10 @@ PreallocXlogFiles(XLogRecPtr endptr) } /* - * Get the log/seg of the latest removed or recycled WAL segment. - * Returns 0 if no WAL segments have been removed since startup. + * 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. + * Returns 0/0 if no WAL segments have been removed since startup. */ void XLogGetLastRemoved(uint32 *log, uint32 *seg) @@ -3247,6 +3249,7 @@ UpdateLastRemovedPtr(char *filename) seg; XLogFromFileName(filename, &tli, &log, &seg); + NextLogSeg(log, seg); SpinLockAcquire(&xlogctl->info_lck); if (log > xlogctl->lastRemovedLog || diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c index d2b9e5c5f9a..3dc794ccc9c 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]; |