aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>2014-01-25 17:34:04 +0200
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>2014-01-25 17:34:04 +0200
commit71c6a8e375b138af8aa46d80226ea9e98f2b94bc (patch)
treeb81980fab354a0b9abfd7e9b1b39b6c3eb6d05b4 /src
parent820f08cabdcbb8998050c3d4873e9619d6d8cba4 (diff)
downloadpostgresql-71c6a8e375b138af8aa46d80226ea9e98f2b94bc.tar.gz
postgresql-71c6a8e375b138af8aa46d80226ea9e98f2b94bc.zip
Add recovery_target='immediate' option.
This allows ending recovery as a consistent state has been reached. Without this, there was no easy way to e.g restore an online backup, without replaying any extra WAL after the backup ended. MauMau and me.
Diffstat (limited to 'src')
-rw-r--r--src/backend/access/transam/recovery.conf.sample6
-rw-r--r--src/backend/access/transam/xlog.c46
-rw-r--r--src/include/access/xlog.h3
3 files changed, 53 insertions, 2 deletions
diff --git a/src/backend/access/transam/recovery.conf.sample b/src/backend/access/transam/recovery.conf.sample
index 673605cfc66..6f7b38eb197 100644
--- a/src/backend/access/transam/recovery.conf.sample
+++ b/src/backend/access/transam/recovery.conf.sample
@@ -81,6 +81,12 @@
#recovery_target_inclusive = true
#
#
+# Alternatively, you can request stopping as soon as a consistent state
+# is reached, by uncommenting this option.
+#
+#recovery_target = 'immediate'
+#
+#
# If you want to recover into a timeline other than the "main line" shown in
# pg_control, specify the timeline number here, or write 'latest' to get
# the latest branch for which there's a history file.
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 9559d6d6aef..b333d820c72 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -5434,6 +5434,19 @@ readRecoveryCommandFile(void)
(errmsg_internal("recovery_target_name = '%s'",
recoveryTargetName)));
}
+ else if (strcmp(item->name, "recovery_target") == 0)
+ {
+ if (strcmp(item->value, "immediate") == 0)
+ recoveryTarget = RECOVERY_TARGET_IMMEDIATE;
+ else
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("invalid recovery_target parameter"),
+ errhint("The only allowed value is 'immediate'")));
+ ereport(DEBUG2,
+ (errmsg_internal("recovery_target = '%s'",
+ item->value)));
+ }
else if (strcmp(item->name, "recovery_target_inclusive") == 0)
{
/*
@@ -5676,7 +5689,20 @@ recoveryStopsBefore(XLogRecord *record)
bool isCommit;
TimestampTz recordXtime = 0;
- /* We only consider stopping before COMMIT or ABORT records. */
+ /* Check if we should stop as soon as reaching consistency */
+ if (recoveryTarget == RECOVERY_TARGET_IMMEDIATE && reachedConsistency)
+ {
+ ereport(LOG,
+ (errmsg("recovery stopping after reaching consistency")));
+
+ recoveryStopAfter = false;
+ recoveryStopXid = InvalidTransactionId;
+ recoveryStopTime = 0;
+ recoveryStopName[0] = '\0';
+ return true;
+ }
+
+ /* Otherwise we only consider stopping before COMMIT or ABORT records. */
if (record->xl_rmid != RM_XACT_ID)
return false;
record_info = record->xl_info & ~XLR_INFO_MASK;
@@ -5825,6 +5851,19 @@ recoveryStopsAfter(XLogRecord *record)
}
}
+ /* Check if we should stop as soon as reaching consistency */
+ if (recoveryTarget == RECOVERY_TARGET_IMMEDIATE && reachedConsistency)
+ {
+ ereport(LOG,
+ (errmsg("recovery stopping after reaching consistency")));
+
+ recoveryStopAfter = true;
+ recoveryStopXid = InvalidTransactionId;
+ recoveryStopTime = 0;
+ recoveryStopName[0] = '\0';
+ return true;
+ }
+
return false;
}
@@ -6246,6 +6285,9 @@ StartupXLOG(void)
ereport(LOG,
(errmsg("starting point-in-time recovery to \"%s\"",
recoveryTargetName)));
+ else if (recoveryTarget == RECOVERY_TARGET_IMMEDIATE)
+ ereport(LOG,
+ (errmsg("starting point-in-time recovery to earliest consistent point")));
else
ereport(LOG,
(errmsg("starting archive recovery")));
@@ -7125,6 +7167,8 @@ StartupXLOG(void)
snprintf(reason, sizeof(reason),
"at restore point \"%s\"",
recoveryStopName);
+ else if (recoveryTarget == RECOVERY_TARGET_IMMEDIATE)
+ snprintf(reason, sizeof(reason), "reached consistency");
else
snprintf(reason, sizeof(reason), "no recovery target specified");
diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h
index 281f51629e4..47e302276b4 100644
--- a/src/include/access/xlog.h
+++ b/src/include/access/xlog.h
@@ -173,7 +173,8 @@ typedef enum
RECOVERY_TARGET_UNSET,
RECOVERY_TARGET_XID,
RECOVERY_TARGET_TIME,
- RECOVERY_TARGET_NAME
+ RECOVERY_TARGET_NAME,
+ RECOVERY_TARGET_IMMEDIATE
} RecoveryTargetType;
extern XLogRecPtr XactLastRecEnd;