aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/transam/xlog.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/access/transam/xlog.c')
-rw-r--r--src/backend/access/transam/xlog.c69
1 files changed, 59 insertions, 10 deletions
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 44e388dbb49..4958f36053b 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.281 2007/09/08 20:31:14 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.282 2007/09/26 22:36:30 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -62,6 +62,7 @@
int CheckPointSegments = 3;
int XLOGbuffers = 8;
int XLogArchiveTimeout = 0;
+bool XLogArchiveMode = false;
char *XLogArchiveCommand = NULL;
char *XLOG_sync_method = NULL;
const char XLOG_sync_method_default[] = DEFAULT_SYNC_METHOD_STR;
@@ -120,8 +121,10 @@ static char *recoveryRestoreCommand = NULL;
static bool recoveryTarget = false;
static bool recoveryTargetExact = false;
static bool recoveryTargetInclusive = true;
+static bool recoveryLogRestartpoints = false;
static TransactionId recoveryTargetXid;
static TimestampTz recoveryTargetTime;
+static TimestampTz recoveryLastXTime = 0;
/* if recoveryStopsHere returns true, it saves actual stop xid/time here */
static TransactionId recoveryStopXid;
@@ -2388,12 +2391,15 @@ RestoreArchivedFile(char *path, const char *xlogfname,
{
char xlogpath[MAXPGPATH];
char xlogRestoreCmd[MAXPGPATH];
+ char lastRestartPointFname[MAXPGPATH];
char *dp;
char *endp;
const char *sp;
int rc;
bool signaled;
struct stat stat_buf;
+ uint32 restartLog;
+ uint32 restartSeg;
/*
* When doing archive recovery, we always prefer an archived log file even
@@ -2466,6 +2472,17 @@ RestoreArchivedFile(char *path, const char *xlogfname,
StrNCpy(dp, xlogfname, endp - dp);
dp += strlen(dp);
break;
+ case 'r':
+ /* %r: filename of last restartpoint */
+ sp++;
+ XLByteToSeg(ControlFile->checkPointCopy.redo,
+ restartLog, restartSeg);
+ XLogFileName(lastRestartPointFname,
+ ControlFile->checkPointCopy.ThisTimeLineID,
+ restartLog, restartSeg);
+ StrNCpy(dp, lastRestartPointFname, endp - dp);
+ dp += strlen(dp);
+ break;
case '%':
/* convert %% to a single % */
sp++;
@@ -4401,6 +4418,21 @@ readRecoveryCommandFile(void)
ereport(LOG,
(errmsg("recovery_target_inclusive = %s", tok2)));
}
+ else if (strcmp(tok1, "log_restartpoints") == 0)
+ {
+ /*
+ * does nothing if a recovery_target is not also set
+ */
+ if (strcmp(tok2, "true") == 0)
+ recoveryLogRestartpoints = true;
+ else
+ {
+ recoveryLogRestartpoints = false;
+ tok2 = "false";
+ }
+ ereport(LOG,
+ (errmsg("log_restartpoints = %s", tok2)));
+ }
else
ereport(FATAL,
(errmsg("unrecognized recovery parameter \"%s\"",
@@ -4564,10 +4596,6 @@ recoveryStopsHere(XLogRecord *record, bool *includeThis)
uint8 record_info;
TimestampTz recordXtime;
- /* Do we have a PITR target at all? */
- if (!recoveryTarget)
- return false;
-
/* We only consider stopping at COMMIT or ABORT records */
if (record->xl_rmid != RM_XACT_ID)
return false;
@@ -4589,6 +4617,13 @@ recoveryStopsHere(XLogRecord *record, bool *includeThis)
else
return false;
+ /* Remember the most recent COMMIT/ABORT time for logging purposes */
+ recoveryLastXTime = recordXtime;
+
+ /* Do we have a PITR target at all? */
+ if (!recoveryTarget)
+ return false;
+
if (recoveryTargetExact)
{
/*
@@ -5015,6 +5050,10 @@ StartupXLOG(void)
ereport(LOG,
(errmsg("redo done at %X/%X",
ReadRecPtr.xlogid, ReadRecPtr.xrecoff)));
+ if (recoveryLastXTime)
+ ereport(LOG,
+ (errmsg("last completed transaction was at log time %s",
+ timestamptz_to_str(recoveryLastXTime))));
InRedo = false;
}
else
@@ -5922,9 +5961,13 @@ RecoveryRestartPoint(const CheckPoint *checkPoint)
ControlFile->time = time(NULL);
UpdateControlFile();
- ereport(DEBUG2,
+ ereport((recoveryLogRestartpoints ? LOG : DEBUG2),
(errmsg("recovery restart point at %X/%X",
checkPoint->redo.xlogid, checkPoint->redo.xrecoff)));
+ if (recoveryLastXTime)
+ ereport((recoveryLogRestartpoints ? LOG : DEBUG2),
+ (errmsg("last completed transaction was at log time %s",
+ timestamptz_to_str(recoveryLastXTime))));
}
/*
@@ -6285,14 +6328,20 @@ pg_start_backup(PG_FUNCTION_ARGS)
if (!superuser())
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
- (errmsg("must be superuser to run a backup"))));
+ errmsg("must be superuser to run a backup")));
if (!XLogArchivingActive())
ereport(ERROR,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
- (errmsg("WAL archiving is not active"),
- (errhint("archive_command must be defined before "
- "online backups can be made safely.")))));
+ errmsg("WAL archiving is not active"),
+ errhint("archive_mode must be enabled at server start.")));
+
+ if (!XLogArchiveCommandSet())
+ ereport(ERROR,
+ (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+ errmsg("WAL archiving is not active"),
+ errhint("archive_command must be defined before "
+ "online backups can be made safely.")));
backupidstr = DatumGetCString(DirectFunctionCall1(textout,
PointerGetDatum(backupid)));