Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitf9ed327

Browse files
committed
Clean up some awkward, inaccurate, and inefficient processing around
MaxStandbyDelay. Use the GUC units mechanism for the value, and choose moreappropriate timestamp functions for performing tests with it. Make theps_activity manipulation in ResolveRecoveryConflictWithVirtualXIDs havebehavior similar to ps_activity code elsewhere, notably not updating thedisplay when update_process_title is off and not truncating the displaycontents at an arbitrarily-chosen length. Improve the docs to be explicitabout what MaxStandbyDelay actually measures, viz the difference betweenprimary and standby servers' clocks, and the possible hazards if their clocksaren't in sync.
1 parent1541632 commitf9ed327

File tree

6 files changed

+78
-94
lines changed

6 files changed

+78
-94
lines changed

‎doc/src/sgml/config.sgml

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.272 2010/04/29 21:36:18 tgl Exp $ -->
1+
<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.273 2010/05/02 02:10:32 tgl Exp $ -->
22

33
<chapter Id="runtime-config">
44
<title>Server Configuration</title>
@@ -1947,13 +1947,12 @@ SET ENABLE_SEQSCAN TO OFF;
19471947
<para>
19481948
When Hot Standby is active, this parameter specifies a wait policy
19491949
for applying WAL entries that conflict with active queries.
1950-
If a conflict should occur the server will delay up to thisnumber
1951-
of secondsbefore it cancels conflicting queries, as
1950+
If a conflict should occur the server will delay up to thislong
1951+
before it cancels conflicting queries, as
19521952
described in <xref linkend="hot-standby-conflict">.
1953-
Typically, this parameter is used only during replication.
1954-
The value is specified in seconds, and -1 causes the standby to wait
1955-
forever for a conflicting query to complete.
19561953
The default is 30 seconds.
1954+
A value of -1 causes the standby to wait forever for a conflicting
1955+
query to complete.
19571956
This parameter can only be set in the <filename>postgresql.conf</>
19581957
file or on the server command line.
19591958
</para>
@@ -1964,7 +1963,7 @@ SET ENABLE_SEQSCAN TO OFF;
19641963
</para>
19651964
<para>
19661965
While it is tempting to believe that <varname>max_standby_delay</>
1967-
is the maximumnumber ofseconds a query can run before
1966+
is the maximumlength oftime a query can run before
19681967
cancellation is possible, this is not true. When a long-running
19691968
query ends, there is a finite time required to apply backlogged
19701969
WAL logs. If a second long-running query appears before the

‎doc/src/sgml/high-availability.sgml

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $PostgreSQL: pgsql/doc/src/sgml/high-availability.sgml,v 1.65 2010/04/29 21:36:18 tgl Exp $ -->
1+
<!-- $PostgreSQL: pgsql/doc/src/sgml/high-availability.sgml,v 1.66 2010/05/02 02:10:32 tgl Exp $ -->
22

33
<chapter id="high-availability">
44
<title>High Availability, Load Balancing, and Replication</title>
@@ -1480,7 +1480,8 @@ if (!triggered)
14801480
There are a number of choices for resolving query conflicts. The default
14811481
is to wait and hope the query finishes. The server will wait
14821482
automatically until the lag between primary and standby is at most
1483-
<varname>max_standby_delay</> seconds. Once that grace period expires,
1483+
<xref linkend="guc-max-standby-delay"> (30 seconds by default).
1484+
Once that grace period expires,
14841485
one of the following actions is taken:
14851486

14861487
<itemizedlist>
@@ -1514,15 +1515,28 @@ if (!triggered)
15141515
</para>
15151516

15161517
<para>
1517-
<varname>max_standby_delay</> is set in <filename>postgresql.conf</>.
1518-
The parameter applies to the server as a whole, so if the delay is consumed
1519-
by a single query then there may be little or no waiting for queries that
1520-
follow, though they will have benefited equally from the initial
1521-
waiting period. The server may take time to catch up again before the grace
1522-
period is available again, though if there is a heavy and constant stream
1523-
of conflicts it may seldom catch up fully.
1518+
Keep in mind that <varname>max_standby_delay</> is compared to the
1519+
difference between the standby server's clock and the transaction
1520+
commit timestamps read from the WAL log. Thus, the grace period
1521+
allowed to any one query on the standby is never more than
1522+
<varname>max_standby_delay</>, and could be considerably less if the
1523+
standby has already fallen behind as a result of waiting for previous
1524+
queries to complete, or as a result of being unable to keep up with a
1525+
heavy update load.
15241526
</para>
15251527

1528+
<caution>
1529+
<para>
1530+
Be sure that the primary and standby servers' clocks are kept in sync;
1531+
otherwise the values compared to <varname>max_standby_delay</> will be
1532+
erroneous, possibly leading to undesirable query cancellations.
1533+
If the clocks are intentionally not in sync, or if there is a large
1534+
propagation delay from primary to standby, it is advisable to set
1535+
<varname>max_standby_delay</> to -1. In any case the value should be
1536+
larger than the largest expected clock skew between primary and standby.
1537+
</para>
1538+
</caution>
1539+
15261540
<para>
15271541
Users should be clear that tables that are regularly and heavily updated on the
15281542
primary server will quickly cause cancellation of longer running queries on
@@ -1656,7 +1670,7 @@ LOG: database system is ready to accept read only connections
16561670
<varname>max_standby_delay</> or even set it to zero, though that is a
16571671
very aggressive setting. If the standby server is tasked as an additional
16581672
server for decision support queries then it might be acceptable to set this
1659-
to a value of many hours (in seconds). It is also possible to set
1673+
to a value of many hours. It is also possible to set
16601674
<varname>max_standby_delay</> to -1 which means wait forever for queries
16611675
to complete; this will be useful when performing
16621676
an archive recovery from a backup.

‎src/backend/access/transam/xlog.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.407 2010/04/29 21:49:03 tgl Exp $
10+
* $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.408 2010/05/02 02:10:33 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -72,7 +72,7 @@ intXLogArchiveTimeout = 0;
7272
boolXLogArchiveMode= false;
7373
char*XLogArchiveCommand=NULL;
7474
boolEnableHotStandby= false;
75-
intMaxStandbyDelay=30;
75+
intMaxStandbyDelay=30*1000;
7676
boolfullPageWrites= true;
7777
boollog_checkpoints= false;
7878
intsync_method=DEFAULT_SYNC_METHOD;

‎src/backend/storage/ipc/standby.c

Lines changed: 41 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
* Portions Copyright (c) 1994, Regents of the University of California
1212
*
1313
* IDENTIFICATION
14-
* $PostgreSQL: pgsql/src/backend/storage/ipc/standby.c,v 1.20 2010/04/28 16:10:42 heikki Exp $
14+
* $PostgreSQL: pgsql/src/backend/storage/ipc/standby.c,v 1.21 2010/05/02 02:10:33 tgl Exp $
1515
*
1616
*-------------------------------------------------------------------------
1717
*/
@@ -124,31 +124,24 @@ static intstandbyWait_us = STANDBY_INITIAL_WAIT_US;
124124
staticbool
125125
WaitExceedsMaxStandbyDelay(void)
126126
{
127-
longdelay_secs;
128-
intdelay_usecs;
129-
130-
if (MaxStandbyDelay==-1)
131-
return false;
132-
133127
/* Are we past max_standby_delay? */
134-
TimestampDifference(GetLatestXLogTime(),GetCurrentTimestamp(),
135-
&delay_secs,&delay_usecs);
136-
if (delay_secs>MaxStandbyDelay)
128+
if (MaxStandbyDelay >=0&&
129+
TimestampDifferenceExceeds(GetLatestXLogTime(),GetCurrentTimestamp(),
130+
MaxStandbyDelay))
137131
return true;
138132

139133
/*
140-
* Sleep, then do bookkeeping.
134+
* Sleep a bit (this is essential to avoid busy-waiting).
141135
*/
142136
pg_usleep(standbyWait_us);
143137

144138
/*
145-
* Progressively increase the sleep times.
139+
* Progressively increase the sleep times, but not to more than 1s,
140+
* since pg_usleep isn't interruptable on some platforms.
146141
*/
147142
standbyWait_us *=2;
148143
if (standbyWait_us>1000000)
149144
standbyWait_us=1000000;
150-
if (standbyWait_us>MaxStandbyDelay*1000000 /4)
151-
standbyWait_us=MaxStandbyDelay*1000000 /4;
152145

153146
return false;
154147
}
@@ -163,50 +156,41 @@ static void
163156
ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId*waitlist,
164157
ProcSignalReasonreason)
165158
{
166-
charwaitactivitymsg[100];
167-
charoldactivitymsg[101];
168-
169159
while (VirtualTransactionIdIsValid(*waitlist))
170160
{
171-
longwait_s;
172-
intwait_us;/* wait in microseconds (us) */
173161
TimestampTzwaitStart;
174-
boollogged;
162+
char*new_status;
163+
164+
pgstat_report_waiting(true);
175165

176166
waitStart=GetCurrentTimestamp();
167+
new_status=NULL;/* we haven't changed the ps display */
168+
169+
/* reset standbyWait_us for each xact we wait for */
177170
standbyWait_us=STANDBY_INITIAL_WAIT_US;
178-
logged= false;
179171

180172
/* wait until the virtual xid is gone */
181173
while (!ConditionalVirtualXactLockTableWait(*waitlist))
182174
{
183175
/*
184-
* Report if we have been waiting for a while now...
176+
* Report via ps if we have been waiting for more than 500 msec
177+
* (should that be configurable?)
185178
*/
186-
TimestampTznow=GetCurrentTimestamp();
187-
188-
TimestampDifference(waitStart,now,&wait_s,&wait_us);
189-
if (!logged&& (wait_s>0||wait_us>500000))
179+
if (update_process_title&&new_status==NULL&&
180+
TimestampDifferenceExceeds(waitStart,GetCurrentTimestamp(),
181+
500))
190182
{
191-
constchar*oldactivitymsgp;
183+
constchar*old_status;
192184
intlen;
193185

194-
oldactivitymsgp=get_ps_display(&len);
195-
196-
if (len>100)
197-
len=100;
198-
199-
memcpy(oldactivitymsg,oldactivitymsgp,len);
200-
oldactivitymsg[len]=0;
201-
202-
snprintf(waitactivitymsg,sizeof(waitactivitymsg),
203-
"waiting for max_standby_delay (%u s)",
186+
old_status=get_ps_display(&len);
187+
new_status= (char*)palloc(len+50);
188+
memcpy(new_status,old_status,len);
189+
snprintf(new_status+len,50,
190+
" waiting for max_standby_delay (%d ms)",
204191
MaxStandbyDelay);
205-
set_ps_display(waitactivitymsg, false);
206-
207-
pgstat_report_waiting(true);
208-
209-
logged= true;
192+
set_ps_display(new_status, false);
193+
new_status[len]='\0';/* truncate off " waiting" */
210194
}
211195

212196
/* Is it time to kill it? */
@@ -225,16 +209,17 @@ ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlist,
225209
* unresponsive backend when system is heavily loaded.
226210
*/
227211
if (pid!=0)
228-
pg_usleep(5000);
212+
pg_usleep(5000L);
229213
}
230214
}
231215

232-
/* Reset ps display */
233-
if (logged)
216+
/* Reset ps displayif we changed it*/
217+
if (new_status)
234218
{
235-
set_ps_display(oldactivitymsg, false);
236-
pgstat_report_waiting(false);
219+
set_ps_display(new_status, false);
220+
pfree(new_status);
237221
}
222+
pgstat_report_waiting(false);
238223

239224
/* The virtual transaction is gone now, wait for the next one */
240225
waitlist++;
@@ -401,7 +386,7 @@ ResolveRecoveryConflictWithBufferPin(void)
401386
*/
402387
SendRecoveryConflictWithBufferPin(PROCSIG_RECOVERY_CONFLICT_BUFFERPIN);
403388
}
404-
elseif (MaxStandbyDelay==-1)
389+
elseif (MaxStandbyDelay<0)
405390
{
406391
/*
407392
* Send out a request to check for buffer pin deadlocks before we
@@ -412,17 +397,11 @@ ResolveRecoveryConflictWithBufferPin(void)
412397
}
413398
else
414399
{
415-
TimestampTznow;
416-
longstandby_delay_secs;/* How far Startup process is lagging */
417-
intstandby_delay_usecs;
418-
419-
now=GetCurrentTimestamp();
400+
TimestampTzthen=GetLatestXLogTime();
401+
TimestampTznow=GetCurrentTimestamp();
420402

421403
/* Are we past max_standby_delay? */
422-
TimestampDifference(GetLatestXLogTime(),now,
423-
&standby_delay_secs,&standby_delay_usecs);
424-
425-
if (standby_delay_secs >=MaxStandbyDelay)
404+
if (TimestampDifferenceExceeds(then,now,MaxStandbyDelay))
426405
{
427406
/*
428407
* We're already behind, so clear a path as quickly as possible.
@@ -434,7 +413,7 @@ ResolveRecoveryConflictWithBufferPin(void)
434413
TimestampTzfin_time;/* Expected wake-up time by timer */
435414
longtimer_delay_secs;/* Amount of time we set timer
436415
* for */
437-
inttimer_delay_usecs=0;
416+
inttimer_delay_usecs;
438417

439418
/*
440419
* Send out a request to check for buffer pin deadlocks before we
@@ -446,12 +425,10 @@ ResolveRecoveryConflictWithBufferPin(void)
446425
/*
447426
* How much longer we should wait?
448427
*/
449-
timer_delay_secs=MaxStandbyDelay-standby_delay_secs;
450-
if (standby_delay_usecs>0)
451-
{
452-
timer_delay_secs-=1;
453-
timer_delay_usecs=1000000-standby_delay_usecs;
454-
}
428+
fin_time=TimestampTzPlusMilliseconds(then,MaxStandbyDelay);
429+
430+
TimestampDifference(now,fin_time,
431+
&timer_delay_secs,&timer_delay_usecs);
455432

456433
/*
457434
* It's possible that the difference is less than a microsecond;
@@ -460,13 +437,6 @@ ResolveRecoveryConflictWithBufferPin(void)
460437
if (timer_delay_secs==0&&timer_delay_usecs==0)
461438
timer_delay_usecs=1;
462439

463-
/*
464-
* When is the finish time? We recheck this if we are woken early.
465-
*/
466-
fin_time=TimestampTzPlusMilliseconds(now,
467-
(timer_delay_secs*1000)+
468-
(timer_delay_usecs /1000));
469-
470440
if (enable_standby_sig_alarm(timer_delay_secs,timer_delay_usecs,fin_time))
471441
sig_alarm_enabled= true;
472442
else

‎src/backend/utils/misc/guc.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
* Written by Peter Eisentraut <peter_e@gmx.net>.
1111
*
1212
* IDENTIFICATION
13-
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.553 2010/04/29 21:36:19 tgl Exp $
13+
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.554 2010/05/02 02:10:33 tgl Exp $
1414
*
1515
*--------------------------------------------------------------------
1616
*/
@@ -1386,10 +1386,11 @@ static struct config_int ConfigureNamesInt[] =
13861386
{
13871387
{"max_standby_delay",PGC_SIGHUP,WAL_SETTINGS,
13881388
gettext_noop("Sets the maximum delay to avoid conflict processing on hot standby servers."),
1389-
NULL
1389+
NULL,
1390+
GUC_UNIT_MS
13901391
},
13911392
&MaxStandbyDelay,
1392-
30,-1,INT_MAX,NULL,NULL
1393+
30*1000,-1,INT_MAX /1000,NULL,NULL
13931394
},
13941395

13951396
{

‎src/backend/utils/misc/postgresql.conf.sample

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@
186186
# - Hot Standby -
187187

188188
#hot_standby = off# allows queries during recovery
189-
#max_standby_delay = 30s# max acceptable lag(s)to allow queries to
189+
#max_standby_delay = 30s# max acceptable lag to allow queries to
190190
# complete without conflict; -1 means forever
191191
#vacuum_defer_cleanup_age = 0# num transactions by which cleanup is deferred
192192

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp