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.
This commit is contained in:
Heikki Linnakangas 2010-11-01 09:56:45 +02:00
parent 76b12e0af7
commit 931b6db39b
2 changed files with 7 additions and 4 deletions

View File

@ -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 ||

View File

@ -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];