aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/src/sgml/backup.sgml10
-rw-r--r--src/backend/access/transam/xlog.c30
2 files changed, 22 insertions, 18 deletions
diff --git a/doc/src/sgml/backup.sgml b/doc/src/sgml/backup.sgml
index 36856b692df..1640c67fd67 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.95.2.2 2007/09/14 13:26:36 momjian Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/backup.sgml,v 2.95.2.3 2007/09/29 01:36:19 tgl Exp $ -->
<chapter id="backup">
<title>Backup and Restore</title>
@@ -1134,11 +1134,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 4ab57244b0b..63500b304a8 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.258.2.1 2007/08/04 01:42:24 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.258.2.2 2007/09/29 01:36:19 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -4468,7 +4468,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);
@@ -4643,7 +4644,7 @@ StartupXLOG(void)
XLogCtlInsert *Insert;
CheckPoint checkPoint;
bool wasShutdown;
- bool needNewTimeLine = false;
+ bool reachedStopPoint = false;
bool haveBackupLabel = false;
XLogRecPtr RecPtr,
LastRec,
@@ -4958,7 +4959,7 @@ StartupXLOG(void)
*/
if (recoveryStopsHere(record, &recoveryApply))
{
- needNewTimeLine = true; /* see below */
+ reachedStopPoint = true; /* see below */
recoveryContinue = false;
if (!recoveryApply)
break;
@@ -5022,11 +5023,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")));
}
@@ -5034,12 +5034,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,