From: Robert Haas <robertmhaas@gmail.com>
To: Fujii Masao <masao.fujii@gmail.com>
Cc: Tom Lane <tgl@sss.pgh.pa.us>
Cc: Greg Stark <gsstark@mit.edu>
Cc: pgsql-hackers@postgresql.org
Subject: Re: time-delayed standbys
Date: Tue, 28 Jun 2011 22:14:56 -0400
Message-ID: <BANLkTimga2ysehLSH=us9mTOWBQw1tk+8Q@mail.gmail.com> (raw)
In-Reply-To: <BANLkTikFhVOhmf_XKERe=MkU3Ht_K7posQ@mail.gmail.com>
References: <BANLkTi==TTzHDqWzwJDjmOf__8YuA7L1jw@mail.gmail.com>
<BANLkTi=QScpDTkUw3iw6JaO15uUvx_P4qg@mail.gmail.com>
<BANLkTimarB9eLhHpW73ja2oGvCaWNQuD6g@mail.gmail.com>
<BANLkTi=hR3vGUDX-SQf=nFcL9ycmrQ6Fcg@mail.gmail.com>
<BANLkTikPdjn98yjSR-VYywyjMe64wdrdDQ@mail.gmail.com>
<26007.1303309175@sss.pgh.pa.us>
<BANLkTikqGottQvyBzrXsARkaWMB2OEMGEA@mail.gmail.com>
<27149.1303312506@sss.pgh.pa.us>
<BANLkTin=22tyhK5zaNm7Nt-Q+MHcsNHdLg@mail.gmail.com>
<BANLkTikFhVOhmf_XKERe=MkU3Ht_K7posQ@mail.gmail.com>
On Wed, Jun 15, 2011 at 1:58 AM, Fujii Masao <masao.fujii@gmail.com> wrote:
> After we run "pg_ctl promote", time-delayed replication should be disabled?
> Otherwise, failover might take very long time when we set recovery_time_delay
> to high value.
PFA a patch that I believe will disable recovery_time_delay after
promotion. The only change from the previous version is:
inline patch 1: src/backend/access/transam/xlog, src/backend/access/transam/xlog.c (+1/-1 lines) download inline-1.patchdiff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlogindex 1dbf792..41b3ae9 100644--- a/src/backend/access/transam/xlog.c+++ b/src/backend/access/transam/xlog.c@@ -5869,7 +5869,7 @@ pg_is_xlog_replay_paused(PG_FUNCTION_ARGS)
static void
recoveryDelay(void)
{
- while (1)+ while (!CheckForStandbyTrigger())
{
long secs;
int microsecs;
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
Patches and attachments:download all (2 files, .tar.gz)time-delayed-standby-v2.patch (application/octet-stream, 6.0K) download
commit 82e22bebb30b6b1d184039131d94ab26a3d4b92e
Author: Robert Haas <rhaas@postgresql.org>
Date: Tue Apr 12 22:50:13 2011 -0700
Support time-delayed standbys.
Review by Greg Stark, Jaime Casanova, Fujii Masao.
diff --git a/doc/src/sgml/recovery-config.sgml b/doc/src/sgml/recovery-config.sgmlindex de60905..375f43b 100644--- a/doc/src/sgml/recovery-config.sgml+++ b/doc/src/sgml/recovery-config.sgml@@ -279,6 +279,28 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows
</listitem>
</varlistentry>
+ <varlistentry id="recovery-time-delay"+ xreflabel="recovery_time_delay">+ <term><varname>recovery_time_delay</varname>+ (<type>integer</type>)+ </term>+ <indexterm>+ <primary><varname>recovery_time_delay</> recovery parameter</primary>+ </indexterm>+ <listitem>+ <para>+ Specifies the amount of time (in milliseconds, if no unit is specified)+ which recovery of transaction commits should lag the master. This+ parameter allows creation of a time-delayed standby. For example, if+ you set this parameter to <literal>5min</literal>, the standby will+ replay each transaction commit only when the system time on the standby+ is at least five minutes past the commit time reported by the master.+ Note that if the master and standby system clocks are not synchronized,+ this might lead to unexpected results.+ </para>+ </listitem>+ </varlistentry>+
</variablelist>
</sect1>
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.cindex 4952d22..41b3ae9 100644--- a/src/backend/access/transam/xlog.c+++ b/src/backend/access/transam/xlog.c@@ -195,6 +195,8 @@ static bool recoveryPauseAtTarget = true;
static TransactionId recoveryTargetXid;
static TimestampTz recoveryTargetTime;
static char *recoveryTargetName;
+static int recovery_time_delay = 0;+static TimestampTz recoveryDelayUntilTime;
/* options taken from recovery.conf for XLOG streaming */
static bool StandbyMode = false;
@@ -606,6 +608,7 @@ static bool recoveryStopsHere(XLogRecord *record, bool *includeThis);
static void recoveryPausesHere(void);
static bool RecoveryIsPaused(void);
static void SetRecoveryPause(bool recoveryPause);
+static void recoveryDelay(void);
static void SetLatestXTime(TimestampTz xtime);
static TimestampTz GetLatestXTime(void);
static void CheckRequiredParameterValues(void);
@@ -5396,6 +5399,19 @@ readRecoveryCommandFile(void)
(errmsg("trigger_file = '%s'",
TriggerFile)));
}
+ else if (strcmp(item->name, "recovery_time_delay") == 0)+ {+ const char *hintmsg;++ if (!parse_int(item->value, &recovery_time_delay, GUC_UNIT_MS,+ &hintmsg))+ ereport(ERROR,+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),+ errmsg("parameter \"%s\" requires a temporal value", "recovery_time_delay"),+ hintmsg ? errhint("%s", _(hintmsg)) : 0));+ ereport(DEBUG2,+ (errmsg("recovery_time_delay = '%s'", item->value)));+ }
else
ereport(FATAL,
(errmsg("unrecognized recovery parameter \"%s\"",
@@ -5579,7 +5595,8 @@ exitArchiveRecovery(TimeLineID endTLI, uint32 endLogId, uint32 endLogSeg)
* We also track the timestamp of the latest applied COMMIT/ABORT
* record in XLogCtl->recoveryLastXTime, for logging purposes.
* Also, some information is saved in recoveryStopXid et al for use in
- * annotating the new timeline's history file.+ * annotating the new timeline's history file; and recoveryDelayUntilTime+ * is updated, for time-delayed standbys.
*/
static bool
recoveryStopsHere(XLogRecord *record, bool *includeThis)
@@ -5589,6 +5606,9 @@ recoveryStopsHere(XLogRecord *record, bool *includeThis)
TimestampTz recordXtime;
char recordRPName[MAXFNAMELEN];
+ /* Clear any previous recovery delay time */+ recoveryDelayUntilTime = 0;+
/* We only consider stopping at COMMIT, ABORT or RESTORE POINT records */
if (record->xl_rmid != RM_XACT_ID && record->xl_rmid != RM_XLOG_ID)
return false;
@@ -5599,6 +5619,10 @@ recoveryStopsHere(XLogRecord *record, bool *includeThis)
recordXactCommitData = (xl_xact_commit *) XLogRecGetData(record);
recordXtime = recordXactCommitData->xact_time;
+ if (recovery_time_delay > 0)+ recoveryDelayUntilTime =+ TimestampTzPlusMilliseconds(recordXactCommitData->xact_time,+ recovery_time_delay);
}
else if (record->xl_rmid == RM_XACT_ID && record_info == XLOG_XACT_ABORT)
{
@@ -5839,6 +5863,47 @@ pg_is_xlog_replay_paused(PG_FUNCTION_ARGS)
}
/*
+ * When recovery_time_delay is set, we wait long enough to make sure we are+ * at least that far behind the master.+ */+static void+recoveryDelay(void)+{+ while (!CheckForStandbyTrigger())+ {+ long secs;+ int microsecs;++ HandleStartupProcInterrupts();+ TimestampDifference(GetCurrentTimestamp(), recoveryDelayUntilTime,+ &secs, µsecs);++ /*+ * If the timestamp we found in the commit record is out of whack, we+ * refuse to wait. In the worst case this might mean going into the+ * tank essentially forever.+ */+ if (secs > (recovery_time_delay / 1000) + 1)+ {+ elog(LOG, "recovery delay is %d seconds, skipping wait of %ld seconds",+ recovery_time_delay / 1000, secs);+ break;+ }++ /*+ * Sleep in intervals of at most one second, so that we can be+ * responsive to interrupts and changes in the system clock.+ */+ if (secs > 0)+ pg_usleep(USECS_PER_SEC);+ else if (microsecs > 0)+ pg_usleep(microsecs);+ else+ break;+ }+}++/*
* Save timestamp of latest processed commit/abort record.
*
* We keep this in XLogCtl, not a simple static variable, so that it can be
@@ -6573,6 +6638,13 @@ StartupXLOG(void)
recoveryPausesHere();
/*
+ * If we've been asked to lag the master, pause until enough+ * time has passed.+ */+ if (recovery_time_delay > 0)+ recoveryDelay();++ /*
* If we are attempting to enter Hot Standby mode, process
* XIDs we see
*/
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-hackers@postgresql.org
Cc: robertmhaas@gmail.com, masao.fujii@gmail.com, tgl@sss.pgh.pa.us, gsstark@mit.edu
Subject: Re: time-delayed standbys
In-Reply-To: <BANLkTimga2ysehLSH=us9mTOWBQw1tk+8Q@mail.gmail.com>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox