diff -rpcd a/doc/src/sgml/backup.sgml b/doc/src/sgml/backup.sgml *** a/doc/src/sgml/backup.sgml 2014-01-22 13:17:06.000000000 +0900 --- b/doc/src/sgml/backup.sgml 2014-01-24 15:39:16.000000000 +0900 *************** restore_command = 'cp /mnt/server/archiv *** 1124,1130 **** If you want to recover to some previous point in time (say, right before the junior DBA dropped your main transaction table), just specify the ! required stopping point in recovery.conf. You can specify the stop point, known as the recovery target, either by date/time, named restore point or by completion of a specific transaction ID. As of this writing only the date/time and named restore point options --- 1124,1130 ---- If you want to recover to some previous point in time (say, right before the junior DBA dropped your main transaction table), just specify the ! required stopping point in recovery.conf. You can specify the stop point, known as the recovery target, either by date/time, named restore point or by completion of a specific transaction ID. As of this writing only the date/time and named restore point options diff -rpcd a/doc/src/sgml/recovery-config.sgml b/doc/src/sgml/recovery-config.sgml *** a/doc/src/sgml/recovery-config.sgml 2014-01-22 13:17:06.000000000 +0900 --- b/doc/src/sgml/recovery-config.sgml 2014-01-24 15:39:16.000000000 +0900 *************** restore_command = 'copy "C:\\server\\arc *** 199,206 **** --- 199,231 ---- Recovery Target Settings + + By default, recovery will recover to the end of the WAL log. The + following parameters can be used to specify an earlier stopping point. + At most one of recovery_target, + recovery_target_name, recovery_target_time, or + recovery_target_xid can be specified. + + + recovery_target = 'immediate' + + recovery_target recovery parameter + + + + This parameter specifies that recovery should end as soon as a + consistency is reached, ie. as early as possible. When restoring from an + online backup, this means the point where taking the backup ended. + + + Technically, this is a string parameter, but 'immediate' + is currently the only allowed value. + + + + recovery_target_name (string) *************** restore_command = 'copy "C:\\server\\arc *** 212,221 **** This parameter specifies the named restore point, created with pg_create_restore_point() to which recovery will proceed. - At most one of recovery_target_name, - or - can be specified. The default is to - recover to the end of the WAL log. --- 237,242 ---- *************** restore_command = 'copy "C:\\server\\arc *** 231,240 **** This parameter specifies the time stamp up to which recovery will proceed. - At most one of recovery_target_time, - or - can be specified. - The default is to recover to the end of the WAL log. The precise stopping point is also influenced by . --- 252,257 ---- *************** restore_command = 'copy "C:\\server\\arc *** 254,268 **** start, transactions can complete in a different numeric order. The transactions that will be recovered are those that committed before (and optionally including) the specified one. - At most one of recovery_target_xid, - or - can be specified. - The default is to recover to the end of the WAL log. The precise stopping point is also influenced by . --- 271,288 ---- start, transactions can complete in a different numeric order. The transactions that will be recovered are those that committed before (and optionally including) the specified one. The precise stopping point is also influenced by . + + + The following options further specify the recovery target, and affect + what happens when the target is reached: + + + diff -rpcd a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c *** a/src/backend/access/transam/xlog.c 2014-01-22 13:17:06.000000000 +0900 --- b/src/backend/access/transam/xlog.c 2014-01-24 16:06:53.000000000 +0900 *************** readRecoveryCommandFile(void) *** 5434,5439 **** --- 5434,5452 ---- (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) { /* *************** recoveryStopsBefore(XLogRecord *record) *** 5676,5682 **** bool isCommit; TimestampTz recordXtime = 0; ! /* 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; --- 5689,5708 ---- bool isCommit; TimestampTz recordXtime = 0; ! /* 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; *************** recoveryStopsAfter(XLogRecord *record) *** 5825,5830 **** --- 5851,5869 ---- } } + /* 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; } *************** StartupXLOG(void) *** 6246,6251 **** --- 6285,6293 ---- 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"))); *************** StartupXLOG(void) *** 7125,7130 **** --- 7167,7174 ---- 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 -rpcd a/src/include/access/xlog.h b/src/include/access/xlog.h *** a/src/include/access/xlog.h 2014-01-22 13:17:06.000000000 +0900 --- b/src/include/access/xlog.h 2014-01-24 15:39:16.000000000 +0900 *************** typedef enum *** 173,179 **** RECOVERY_TARGET_UNSET, RECOVERY_TARGET_XID, RECOVERY_TARGET_TIME, ! RECOVERY_TARGET_NAME } RecoveryTargetType; extern XLogRecPtr XactLastRecEnd; --- 173,180 ---- RECOVERY_TARGET_UNSET, RECOVERY_TARGET_XID, RECOVERY_TARGET_TIME, ! RECOVERY_TARGET_NAME, ! RECOVERY_TARGET_IMMEDIATE } RecoveryTargetType; extern XLogRecPtr XactLastRecEnd;