<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
 
         *
         * 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);
        XLogCtlInsert *Insert;
        CheckPoint      checkPoint;
        bool            wasShutdown;
-       bool            needNewTimeLine = false;
+       bool            reachedStopPoint = false;
        bool            haveBackupLabel = false;
        XLogRecPtr      RecPtr,
                                LastRec,
                                 */
                                if (recoveryStopsHere(record, &recoveryApply))
                                {
-                                       needNewTimeLine = true;         /* see below */
+                                       reachedStopPoint = true;                /* see below */
                                        recoveryContinue = false;
                                        if (!recoveryApply)
                                                break;
         */
        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")));
        }
        /*
         * 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,