postgres.git / summary / log / commit / refs

commit    fb886c153bc168eeb1c3fd2f24562b5b808357d6
Author:   Andres Freund <andres@anarazel.de>
Date:     Wed Jun 21 21:14:45 2017 +0000

    Fix possibility of creating a "phantom" segment after promotion.
    
    When promoting a standby just after a XLOG_SWITCH record was replayed,
    and next segment(s) are already are locally available (via walsender,
    restore_command + trigger/recovery target), that segment could
    accidentally be recycled onto the past of the new timeline.  Later
    checkpointer would create a .ready file for it, assuming there was an
    error during creation, and it would get archived.  That causes trouble
    if another standby is later brought up from a basebackup from before
    the timeline creation, because it would try to read the
    segment, because XLogFileReadAnyTLI just tries all possible timelines,
    which doesn't have valid contents.  Thus replay would fail.
    
    The problem, if already occurred, can be fixed by removing the segment
    and/or having restore_command filter it out.
    
    The reason for the creation of such "phantom" segments was, that after
    an XLOG_SWITCH record the EndOfLog variable points to the beginning of
    the next segment, and RemoveXlogFile() used XLByteToPrevSeg().
    Normally RemoveXlogFile() doing so is harmless, because the last
    segment will still exist preventing InstallXLogFileSegment() from
    causing harm, but just after promotion there's no previous segment on
    the new timeline.
    
    Fix that by using XLByteToSeg() instead of XLByteToPrevSeg().
    
    Author: Andres Freund
    Reported-By: Greg Burek
    Discussion: https://postgr.es/m/20170619073026.zcwpe6mydsaz5ygd@alap3.anarazel.de
    Backpatch: 9.2-, bug older than all supported versions


src/backend/access/transam/xlog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 48eecfc84a1..e60433ba0ba 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -3974,7 +3974,7 @@ RemoveXlogFile(const char *segname, XLogRecPtr PriorRedoPtr, XLogRecPtr endptr) /* * Initialize info about where to try to recycle to. */ - XLByteToPrevSeg(endptr, endlogSegNo); + XLByteToSeg(endptr, endlogSegNo); if (PriorRedoPtr == InvalidXLogRecPtr) recycleSegNo = endlogSegNo + 10; else [parent: 780b3a4c43fd]