From 71c6a8e375b138af8aa46d80226ea9e98f2b94bc Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas <heikki.linnakangas@iki.fi> Date: Sat, 25 Jan 2014 17:34:04 +0200 Subject: [PATCH] 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. --- doc/src/sgml/backup.sgml | 2 +- doc/src/sgml/recovery-config.sgml | 44 +++++++++++++----- .../access/transam/recovery.conf.sample | 6 +++ src/backend/access/transam/xlog.c | 46 ++++++++++++++++++- src/include/access/xlog.h | 3 +- 5 files changed, 86 insertions(+), 15 deletions(-) diff --git a/doc/src/sgml/backup.sgml b/doc/src/sgml/backup.sgml index a2361d780fb..854b5fde41c 100644 --- a/doc/src/sgml/backup.sgml +++ b/doc/src/sgml/backup.sgml @@ -1124,7 +1124,7 @@ restore_command = 'cp /mnt/server/archivedir/%f %p' <para> 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 <filename>recovery.conf</>. You can specify + required <link linkend="recovery-target-settings">stopping point</link> in <filename>recovery.conf</>. You can specify the stop point, known as the <quote>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 --git a/doc/src/sgml/recovery-config.sgml b/doc/src/sgml/recovery-config.sgml index 550cdce6f99..b818197299d 100644 --- a/doc/src/sgml/recovery-config.sgml +++ b/doc/src/sgml/recovery-config.sgml @@ -199,8 +199,33 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows <sect1 id="recovery-target-settings"> <title>Recovery Target Settings</title> + <para> + 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 <varname>recovery_target</>, + <varname>recovery_target_name</>, <varname>recovery_target_time</>, or + <varname>recovery_target_xid</> can be specified. + </para> <variablelist> + <varlistentry id="recovery-target" xreflabel="recovery_target_name"> + <term><varname>recovery_target</varname><literal> = 'immediate'</literal></term> + <indexterm> + <primary><varname>recovery_target</> recovery parameter</primary> + </indexterm> + <listitem> + <para> + 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. + </para> + <para> + Technically, this is a string parameter, but <literal>'immediate'</> + is currently the only allowed value. + </para> + </listitem> + </varlistentry> + <varlistentry id="recovery-target-name" xreflabel="recovery_target_name"> <term><varname>recovery_target_name</varname> (<type>string</type>) @@ -212,10 +237,6 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows <para> This parameter specifies the named restore point, created with <function>pg_create_restore_point()</> to which recovery will proceed. - At most one of <varname>recovery_target_name</>, - <xref linkend="recovery-target-time"> or - <xref linkend="recovery-target-xid"> can be specified. The default is to - recover to the end of the WAL log. </para> </listitem> </varlistentry> @@ -231,10 +252,6 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows <para> This parameter specifies the time stamp up to which recovery will proceed. - At most one of <varname>recovery_target_time</>, - <xref linkend="recovery-target-name"> or - <xref linkend="recovery-target-xid"> can be specified. - The default is to recover to the end of the WAL log. The precise stopping point is also influenced by <xref linkend="recovery-target-inclusive">. </para> @@ -254,15 +271,18 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 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 <varname>recovery_target_xid</>, - <xref linkend="recovery-target-name"> or - <xref linkend="recovery-target-time"> can be specified. - The default is to recover to the end of the WAL log. The precise stopping point is also influenced by <xref linkend="recovery-target-inclusive">. </para> </listitem> </varlistentry> + </variablelist> + <para> + The following options further specify the recovery target, and affect + what happens when the target is reached: + </para> + + <variablelist> <varlistentry id="recovery-target-inclusive" xreflabel="recovery_target_inclusive"> 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; -- GitLab