*** a/src/backend/access/transam/xlog.c
--- b/src/backend/access/transam/xlog.c
***************
*** 2923,2934 **** XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock)
   * srcTLI, srclog, srcseg: identify segment to be copied (could be from
   *		a different timeline)
   *
   * Currently this is only used during recovery, and so there are no locking
   * considerations.  But we should be just as tense as XLogFileInit to avoid
   * emplacing a bogus file.
   */
  static void
! XLogFileCopy(XLogSegNo destsegno, TimeLineID srcTLI, XLogSegNo srcsegno)
  {
  	char		path[MAXPGPATH];
  	char		tmppath[MAXPGPATH];
--- 2923,2937 ----
   * srcTLI, srclog, srcseg: identify segment to be copied (could be from
   *		a different timeline)
   *
+  * upto: how much of the source file to copy? (the rest is filled with zeros)
+  *
   * Currently this is only used during recovery, and so there are no locking
   * considerations.  But we should be just as tense as XLogFileInit to avoid
   * emplacing a bogus file.
   */
  static void
! XLogFileCopy(XLogSegNo destsegno, TimeLineID srcTLI, XLogSegNo srcsegno,
! 			 int upto)
  {
  	char		path[MAXPGPATH];
  	char		tmppath[MAXPGPATH];
***************
*** 2967,2982 **** XLogFileCopy(XLogSegNo destsegno, TimeLineID srcTLI, XLogSegNo srcsegno)
  	 */
  	for (nbytes = 0; nbytes < XLogSegSize; nbytes += sizeof(buffer))
  	{
! 		errno = 0;
! 		if ((int) read(srcfd, buffer, sizeof(buffer)) != (int) sizeof(buffer))
  		{
! 			if (errno != 0)
! 				ereport(ERROR,
! 						(errcode_for_file_access(),
! 						 errmsg("could not read file \"%s\": %m", path)));
! 			else
! 				ereport(ERROR,
! 						(errmsg("not enough data in file \"%s\"", path)));
  		}
  		errno = 0;
  		if ((int) write(fd, buffer, sizeof(buffer)) != (int) sizeof(buffer))
--- 2970,3000 ----
  	 */
  	for (nbytes = 0; nbytes < XLogSegSize; nbytes += sizeof(buffer))
  	{
! 		int			nread;
! 
! 		nread = upto - nbytes;
! 
! 		/*
! 		 * The part that is not read from the source file is filled with zeros.
! 		 */
! 		if (nread < sizeof(buffer))
! 			memset(buffer, 0, sizeof(buffer));
! 
! 		if (nread > 0)
  		{
! 			if (nread > sizeof(buffer))
! 				nread = sizeof(buffer);
! 			errno = 0;
! 			if (read(srcfd, buffer, nread) != nread)
! 			{
! 				if (errno != 0)
! 					ereport(ERROR,
! 							(errcode_for_file_access(),
! 							 errmsg("could not read file \"%s\": %m", path)));
! 				else
! 					ereport(ERROR,
! 							(errmsg("not enough data in file \"%s\"", path)));
! 			}
  		}
  		errno = 0;
  		if ((int) write(fd, buffer, sizeof(buffer)) != (int) sizeof(buffer))
***************
*** 4984,4991 **** exitArchiveRecovery(TimeLineID endTLI, XLogRecPtr endOfLog)
  	char		recoveryPath[MAXPGPATH];
  	char		xlogfname[MAXFNAMELEN];
  	XLogSegNo	endLogSegNo;
  
! 	XLByteToPrevSeg(endOfLog, endLogSegNo);	
  
  	/*
  	 * We are no longer in archive recovery state.
--- 5002,5011 ----
  	char		recoveryPath[MAXPGPATH];
  	char		xlogfname[MAXFNAMELEN];
  	XLogSegNo	endLogSegNo;
+ 	XLogSegNo	startLogSegNo;
  
! 	/* we always switch to a new timeline after archive recovery */
! 	Assert(endTLI != ThisTimeLineID);
  
  	/*
  	 * We are no longer in archive recovery state.
***************
*** 5008,5026 **** exitArchiveRecovery(TimeLineID endTLI, XLogRecPtr endOfLog)
  	}
  
  	/*
! 	 * 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. (Unless the switch happens to be at a segment
! 	 * boundary.)
  	 *
  	 * Notify the archiver that the last WAL segment of the old timeline is
  	 * ready to copy to archival storage if its .done file doesn't exist
  	 * (e.g., if it's the restored WAL file, it's expected to have .done file).
  	 * Otherwise, it is not archived for a while.
  	 */
! 	if (endTLI != ThisTimeLineID && endOfLog % XLOG_SEG_SIZE != 0)
  	{
! 		XLogFileCopy(endLogSegNo, endTLI, endLogSegNo);
  
  		/* Create .ready file only when neither .ready nor .done files exist */
  		if (XLogArchivingActive())
--- 5028,5056 ----
  	}
  
  	/*
! 	 * Calculate the last segment on the old timeline, and the first segment
! 	 * on the new timeline. If the switch happens in the middle of a segment,
! 	 * they are the same, but if the switch happens exactly at a segment
! 	 * boundary, startLogSegNo will be endLogSegNo + 1.
! 	 */
! 	XLByteToPrevSeg(endOfLog, endLogSegNo);
! 	XLByteToSeg(endOfLog, startLogSegNo);
! 
! 	/*
! 	 * Initialize the starting WAL segment for the new timeline. If the switch
! 	 * happens in the middle of a segment, copy data from the last WAL segment
! 	 * of the old timeline up to the switch point, to the starting WAL segment
! 	 * on the new timeline.
  	 *
  	 * Notify the archiver that the last WAL segment of the old timeline is
  	 * ready to copy to archival storage if its .done file doesn't exist
  	 * (e.g., if it's the restored WAL file, it's expected to have .done file).
  	 * Otherwise, it is not archived for a while.
  	 */
! 	if (endLogSegNo == startLogSegNo)
  	{
! 		XLogFileCopy(startLogSegNo, endTLI, endLogSegNo,
! 					 endOfLog % XLOG_SEG_SIZE);
  
  		/* Create .ready file only when neither .ready nor .done files exist */
  		if (XLogArchivingActive())
***************
*** 5033,5046 **** exitArchiveRecovery(TimeLineID endTLI, XLogRecPtr endOfLog)
  	{
  		bool		use_existent = true;
  
! 		XLogFileInit(xlogfname, &use_existent, true);
  	}
  
  	/*
  	 * Let's just make real sure there are not .ready or .done flags posted
  	 * for the new segment.
  	 */
! 	XLogFileName(xlogfname, ThisTimeLineID, endLogSegNo);
  	XLogArchiveCleanup(xlogfname);
  
  	/*
--- 5063,5076 ----
  	{
  		bool		use_existent = true;
  
! 		XLogFileInit(startLogSegNo, &use_existent, true);
  	}
  
  	/*
  	 * Let's just make real sure there are not .ready or .done flags posted
  	 * for the new segment.
  	 */
! 	XLogFileName(xlogfname, ThisTimeLineID, startLogSegNo);
  	XLogArchiveCleanup(xlogfname);
  
  	/*
***************
*** 5628,5634 **** StartupXLOG(void)
  	XLogRecPtr	RecPtr,
  				checkPointLoc,
  				EndOfLog;
! 	XLogSegNo	endLogSegNo;
  	TimeLineID	PrevTimeLineID;
  	XLogRecord *record;
  	TransactionId oldestActiveXID;
--- 5658,5664 ----
  	XLogRecPtr	RecPtr,
  				checkPointLoc,
  				EndOfLog;
! 	XLogSegNo	startLogSegNo;
  	TimeLineID	PrevTimeLineID;
  	XLogRecord *record;
  	TransactionId oldestActiveXID;
***************
*** 6608,6614 **** StartupXLOG(void)
  	 */
  	record = ReadRecord(xlogreader, LastRec, PANIC, false);
  	EndOfLog = EndRecPtr;
! 	XLByteToPrevSeg(EndOfLog, endLogSegNo);
  
  	/*
  	 * Complain if we did not roll forward far enough to render the backup
--- 6638,6644 ----
  	 */
  	record = ReadRecord(xlogreader, LastRec, PANIC, false);
  	EndOfLog = EndRecPtr;
! 	XLByteToSeg(EndOfLog, startLogSegNo);
  
  	/*
  	 * Complain if we did not roll forward far enough to render the backup
***************
*** 6716,6722 **** StartupXLOG(void)
  	 * buffer cache using the block containing the last record from the
  	 * previous incarnation.
  	 */
! 	openLogSegNo = endLogSegNo;
  	openLogFile = XLogFileOpen(openLogSegNo);
  	openLogOff = 0;
  	Insert = &XLogCtl->Insert;
--- 6746,6752 ----
  	 * buffer cache using the block containing the last record from the
  	 * previous incarnation.
  	 */
! 	openLogSegNo = startLogSegNo;
  	openLogFile = XLogFileOpen(openLogSegNo);
  	openLogOff = 0;
  	Insert = &XLogCtl->Insert;
