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:
parent
76b12e0af7
commit
931b6db39b
@ -364,7 +364,7 @@ typedef struct XLogCtlData
|
|||||||
uint32 ckptXidEpoch; /* nextXID & epoch of latest checkpoint */
|
uint32 ckptXidEpoch; /* nextXID & epoch of latest checkpoint */
|
||||||
TransactionId ckptXid;
|
TransactionId ckptXid;
|
||||||
XLogRecPtr asyncXactLSN; /* LSN of newest async commit/abort */
|
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;
|
uint32 lastRemovedSeg;
|
||||||
|
|
||||||
/* Protected by WALWriteLock: */
|
/* Protected by WALWriteLock: */
|
||||||
@ -3218,8 +3218,10 @@ PreallocXlogFiles(XLogRecPtr endptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the log/seg of the latest removed or recycled WAL segment.
|
* Get the log/seg of the first WAL segment that has not been removed or
|
||||||
* Returns 0 if no WAL segments have been removed since startup.
|
* 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
|
void
|
||||||
XLogGetLastRemoved(uint32 *log, uint32 *seg)
|
XLogGetLastRemoved(uint32 *log, uint32 *seg)
|
||||||
@ -3247,6 +3249,7 @@ UpdateLastRemovedPtr(char *filename)
|
|||||||
seg;
|
seg;
|
||||||
|
|
||||||
XLogFromFileName(filename, &tli, &log, &seg);
|
XLogFromFileName(filename, &tli, &log, &seg);
|
||||||
|
NextLogSeg(log, seg);
|
||||||
|
|
||||||
SpinLockAcquire(&xlogctl->info_lck);
|
SpinLockAcquire(&xlogctl->info_lck);
|
||||||
if (log > xlogctl->lastRemovedLog ||
|
if (log > xlogctl->lastRemovedLog ||
|
||||||
|
@ -654,7 +654,7 @@ XLogRead(char *buf, XLogRecPtr recptr, Size nbytes)
|
|||||||
XLogGetLastRemoved(&lastRemovedLog, &lastRemovedSeg);
|
XLogGetLastRemoved(&lastRemovedLog, &lastRemovedSeg);
|
||||||
XLByteToSeg(startRecPtr, log, seg);
|
XLByteToSeg(startRecPtr, log, seg);
|
||||||
if (log < lastRemovedLog ||
|
if (log < lastRemovedLog ||
|
||||||
(log == lastRemovedLog && seg <= lastRemovedSeg))
|
(log == lastRemovedLog && seg < lastRemovedSeg))
|
||||||
{
|
{
|
||||||
char filename[MAXFNAMELEN];
|
char filename[MAXFNAMELEN];
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user