exitArchiveRecovery(TimeLineID endTLI, XLogSegNo endLogSegNo)
{
	char		recoveryPath[MAXPGPATH];
	char		xlogpath[MAXPGPATH];

	/*
	 * We are no longer in archive recovery state.
	 */
	InArchiveRecovery = false;

	/*
	 * Update min recovery point one last time.
	 */
	UpdateMinRecoveryPoint(InvalidXLogRecPtr, true);

	/*
	 * If the ending log segment is still open, close it (to avoid problems on
	 * Windows with trying to rename or delete an open file).
	 */
	if (readFile >= 0)
	{
		close(readFile);
		readFile = -1;
	}

	/*
	 * 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);
		}
	}

	/*
	 * Let's just make real sure there are not .ready or .done flags posted
	 * for the new segment.
	 */
	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 */

	/*
	 * Rename the config file out of the way, so that we don't accidentally
	 * re-enter archive recovery mode in a subsequent crash.
	 */
	unlink(RECOVERY_COMMAND_DONE);
	if (rename(RECOVERY_COMMAND_FILE, RECOVERY_COMMAND_DONE) != 0)
		ereport(FATAL,
				(errcode_for_file_access(),
				 errmsg("could not rename file \"%s\" to \"%s\": %m",
						RECOVERY_COMMAND_FILE, RECOVERY_COMMAND_DONE)));

	ereport(LOG,
			(errmsg("archive recovery complete")));
}
exitArchiveRecovery(TimeLineID endTLI, XLogSegNo endLogSegNo)
{
	char		recoveryPath[MAXPGPATH];
	char		xlogpath[MAXPGPATH];

	 
	InArchiveRecovery = false;

	 
	UpdateMinRecoveryPoint(InvalidXLogRecPtr, true);

	 
	if (readFile >= 0)
	{
		close(readFile);
		readFile = -1;
	}

	 
	if (endTLI != ThisTimeLineID)
	{
		XLogFileCopy(endLogSegNo, endTLI, endLogSegNo);

		if (XLogArchivingActive())
		{
			XLogFileName(xlogpath, endTLI, endLogSegNo);
			XLogArchiveNotify(xlogpath);
		}
	}

	 
	XLogFileName(xlogpath, ThisTimeLineID, endLogSegNo);
	XLogArchiveCleanup(xlogpath);

	 
	snprintf(recoveryPath, MAXPGPATH, XLOGDIR "/RECOVERYXLOG");
	unlink(recoveryPath);		 

	 
	snprintf(recoveryPath, MAXPGPATH, XLOGDIR "/RECOVERYHISTORY");
	unlink(recoveryPath);		 

	 
	unlink(RECOVERY_COMMAND_DONE);
	if (rename(RECOVERY_COMMAND_FILE, RECOVERY_COMMAND_DONE) != 0)
		ereport(FATAL,
				(errcode_for_file_access(),
				 errmsg("could not rename file \"%s\" to \"%s\": %m",
						RECOVERY_COMMAND_FILE, RECOVERY_COMMAND_DONE)));

	ereport(LOG,
			(errmsg("archive recovery complete")));
}