diff --git a/doc/src/sgml/backup.sgml b/doc/src/sgml/backup.sgml
index e34fc0f3a67697632fb2be45198989093ee3368f..5e8549a2c038af9961bfc58c87270fb556548aa6 100644
--- a/doc/src/sgml/backup.sgml
+++ b/doc/src/sgml/backup.sgml
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/backup.sgml,v 2.102 2007/09/26 22:36:30 tgl Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/backup.sgml,v 2.103 2007/09/29 01:36:10 tgl Exp $ -->
 
 <chapter id="backup">
  <title>Backup and Restore</title>
@@ -1174,11 +1174,9 @@ restore_command = 'copy /mnt/server/archivedir/%f "%p"'  # Windows
 
    <para>
     To deal with these problems, <productname>PostgreSQL</> has a notion
-    of <firstterm>timelines</>.  Each time you recover to a point-in-time
-    earlier than the end of the WAL sequence, a new timeline is created
-    to identify the series of WAL records generated after that recovery.
-    (If recovery proceeds all the way to the end of WAL, however, we do not
-    start a new timeline: we just extend the existing one.)  The timeline
+    of <firstterm>timelines</>.  Whenever an archive recovery is completed,
+    a new timeline is created to identify the series of WAL records
+    generated after that recovery.  The timeline
     ID number is part of WAL segment file names, and so a new timeline does
     not overwrite the WAL data generated by previous timelines.  It is
     in fact possible to archive many different timelines.  While that might
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 4958f36053b487ccf3056700b02716262f78b86b..f258b7f7f0463056384fd1bdc37614ed53834208 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.282 2007/09/26 22:36:30 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.283 2007/09/29 01:36:10 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -4518,7 +4518,8 @@ exitArchiveRecovery(TimeLineID endTLI, uint32 endLogId, uint32 endLogSeg)
 	 *
 	 * 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.
+	 * of overwriting any existing file.  (This is, in fact, always the case
+	 * at present.)
 	 */
 	snprintf(recoveryPath, MAXPGPATH, XLOGDIR "/RECOVERYXLOG");
 	XLogFilePath(xlogpath, ThisTimeLineID, endLogId, endLogSeg);
@@ -4700,7 +4701,7 @@ StartupXLOG(void)
 	XLogCtlInsert *Insert;
 	CheckPoint	checkPoint;
 	bool		wasShutdown;
-	bool		needNewTimeLine = false;
+	bool		reachedStopPoint = false;
 	bool		haveBackupLabel = false;
 	XLogRecPtr	RecPtr,
 				LastRec,
@@ -5010,7 +5011,7 @@ StartupXLOG(void)
 				 */
 				if (recoveryStopsHere(record, &recoveryApply))
 				{
-					needNewTimeLine = true;		/* see below */
+					reachedStopPoint = true;		/* see below */
 					recoveryContinue = false;
 					if (!recoveryApply)
 						break;
@@ -5078,11 +5079,10 @@ StartupXLOG(void)
 	 */
 	if (XLByteLT(EndOfLog, ControlFile->minRecoveryPoint))
 	{
-		if (needNewTimeLine)	/* stopped because of stop request */
+		if (reachedStopPoint)	/* stopped because of stop request */
 			ereport(FATAL,
 					(errmsg("requested recovery stop point is before end time of backup dump")));
-		else
-			/* ran off end of WAL */
+		else					/* ran off end of WAL */
 			ereport(FATAL,
 					(errmsg("WAL ends before end time of backup dump")));
 	}
@@ -5090,12 +5090,18 @@ StartupXLOG(void)
 	/*
 	 * Consider whether we need to assign a new timeline ID.
 	 *
-	 * If we stopped short of the end of WAL during recovery, then we are
-	 * generating a new timeline and must assign it a unique new ID.
-	 * Otherwise, we can just extend the timeline we were in when we ran out
-	 * of WAL.
+	 * If we are doing an archive recovery, we always assign a new ID.  This
+	 * handles a couple of issues.  If we stopped short of the end of WAL
+	 * during recovery, then we are clearly generating a new timeline and must
+	 * assign it a unique new ID.  Even if we ran to the end, modifying the
+	 * current last segment is problematic because it may result in trying
+	 * to overwrite an already-archived copy of that segment, and we encourage
+	 * DBAs to make their archive_commands reject that.  We can dodge the
+	 * problem by making the new active segment have a new timeline ID.
+	 *
+	 * In a normal crash recovery, we can just extend the timeline we were in.
 	 */
-	if (needNewTimeLine)
+	if (InArchiveRecovery)
 	{
 		ThisTimeLineID = findNewestTimeLine(recoveryTargetTLI) + 1;
 		ereport(LOG,