On Fri, Dec 20, 2013 at 9:21 PM, MauMau <maumau...@gmail.com> wrote: > From: "Fujii Masao" <masao.fu...@gmail.com> > >> ! if (source == XLOG_FROM_ARCHIVE && StandbyModeRequested) >> >> Even when standby_mode is not enabled, we can use cascade replication and >> it needs the accumulated WAL files. So I think that >> AllowCascadeReplication() >> should be added into this condition. >> >> ! snprintf(recoveryPath, MAXPGPATH, XLOGDIR "/RECOVERYXLOG"); >> ! XLogFilePath(xlogpath, ThisTimeLineID, endLogSegNo); >> ! >> ! if (restoredFromArchive) >> >> Don't we need to check !StandbyModeRequested and >> !AllowCascadeReplication() >> here? > > > Oh, you are correct. Okay, done.
Thanks! The patch looks good to me. Attached is the updated version of the patch. I added the comments. Did you test whether this patch works properly in several recovery cases? Regards, -- Fujii Masao
*** a/src/backend/access/transam/xlog.c --- b/src/backend/access/transam/xlog.c *************** *** 3772,3781 **** XLogFileRead(XLogSegNo segno, int emode, TimeLineID tli, } /* ! * If the segment was fetched from archival storage, replace the existing ! * xlog segment (if any) with the archival version. */ ! if (source == XLOG_FROM_ARCHIVE) { KeepFileRestoredFromArchive(path, xlogfname); --- 3772,3792 ---- } /* ! * If the segment was fetched from archival storage and either cascading ! * replication or standby_mode is enabled, replace the existing xlog ! * segment (if any) with the archival version. Cascading replication needs ! * this replacement so that cascading walsender can send the xlog segment ! * which was restored from the archive. When standby_mode is enabled, ! * fast promotion is performed at the end of recovery, and also needs this ! * replacement so that the crash recovery just after fast promotion can ! * replay all the required segments from pg_xlog. ! * ! * If the replacement is not required, the segments are always restored onto ! * the same file named RECOVERYXLOG from the archive. This prevents the ! * large increase of segments in pg_xlog. */ ! if (source == XLOG_FROM_ARCHIVE && ! (AllowCascadeReplication() || StandbyModeRequested)) { KeepFileRestoredFromArchive(path, xlogfname); *************** *** 5572,5593 **** exitArchiveRecovery(TimeLineID endTLI, XLogSegNo endLogSegNo) } /* ! * If we are establishing a new timeline, we have to copy data from the ! * last WAL segment of the old timeline to create a starting WAL segment ! * for the new timeline. * ! * Notify the archiver that the last WAL segment of the old timeline is ! * ready to copy to archival storage. Otherwise, it is not archived for a ! * while. */ ! if (endTLI != ThisTimeLineID) { ! XLogFileCopy(endLogSegNo, endTLI, endLogSegNo); ! if (XLogArchivingActive()) { ! XLogFileName(xlogpath, endTLI, endLogSegNo); ! XLogArchiveNotify(xlogpath); } } --- 5583,5646 ---- } /* ! * If the segment was fetched from archival storage and neither cascading ! * replication nor fast promotion is enabled, we replace the existing xlog ! * segment (if any) with the archival version named RECOVERYXLOG. This is ! * because whatever is in XLOGDIR is very possibly older than what we have ! * from the archives, since it could have come from restoring a PGDATA ! * backup. In any case, the archival version certainly is more ! * descriptive of what our current database state is, because that is what ! * we replayed from. ! * ! * Note that if we are establishing a new timeline, ThisTimeLineID is ! * already set to the new value, and so we will create a new file instead ! * of overwriting any existing file. (This is, in fact, always the case ! * at present.) * ! * If either cascading replication or fast promotion is enabled, we don't ! * need the replacement here because it has already done just after the ! * segment was restored from the archive. */ ! snprintf(recoveryPath, MAXPGPATH, XLOGDIR "/RECOVERYXLOG"); ! XLogFilePath(xlogpath, ThisTimeLineID, endLogSegNo); ! ! if (restoredFromArchive && ! !AllowCascadeReplication() && !StandbyModeRequested) { ! unlink(xlogpath); /* might or might not exist */ ! if (rename(recoveryPath, xlogpath) != 0) ! ereport(FATAL, ! (errcode_for_file_access(), ! errmsg("could not rename file \"%s\" to \"%s\": %m", ! recoveryPath, xlogpath))); ! /* XXX might we need to fix permissions on the file? */ ! } ! else ! { ! /* ! * Since there might be a partial WAL segment named RECOVERYXLOG, ! * get rid of it. ! */ ! unlink(recoveryPath); /* ignore any error */ ! /* ! * If we are establishing a new timeline, we have to copy data from ! * the last WAL segment of the old timeline to create a starting WAL ! * segment for the new timeline. ! * ! * Notify the archiver that the last WAL segment of the old timeline ! * is ready to copy to archival storage. Otherwise, it is not archived ! * for a while. ! */ ! if (endTLI != ThisTimeLineID) { ! XLogFileCopy(endLogSegNo, endTLI, endLogSegNo); ! ! if (XLogArchivingActive()) ! { ! XLogFileName(xlogpath, endTLI, endLogSegNo); ! XLogArchiveNotify(xlogpath); ! } } } *************** *** 5598,5610 **** exitArchiveRecovery(TimeLineID endTLI, XLogSegNo endLogSegNo) XLogFileName(xlogpath, ThisTimeLineID, endLogSegNo); XLogArchiveCleanup(xlogpath); - /* - * Since there might be a partial WAL segment named RECOVERYXLOG, get rid - * of it. - */ - snprintf(recoveryPath, MAXPGPATH, XLOGDIR "/RECOVERYXLOG"); - unlink(recoveryPath); /* ignore any error */ - /* Get rid of any remaining recovered timeline-history file, too */ snprintf(recoveryPath, MAXPGPATH, XLOGDIR "/RECOVERYHISTORY"); unlink(recoveryPath); /* ignore any error */ --- 5651,5656 ----
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers