summaryrefslogtreecommitdiff
path: root/src/backend/storage/ipc
diff options
context:
space:
mode:
authorSimon Riggs2010-05-26 19:52:52 +0000
committerSimon Riggs2010-05-26 19:52:52 +0000
commitf9dbac94767d64f6a1174506b6e61db34729e015 (patch)
tree4e92ee8ac96f7c2d9932c128bc73f7d7f1a95625 /src/backend/storage/ipc
parent5234a9524510bdff3a339f204d2655e7ce2eb3b5 (diff)
HS Defer buffer pin deadlock check until deadlock_timeout has expired.
During Hot Standby we need to check for buffer pin deadlocks when the Startup process begins to wait, in case it never wakes up again. We previously made the deadlock check immediately on the basis it was cheap, though clearer thinking and prima facie evidence shows that was too simple. Refactor existing code to make it easy to add in deferral of deadlock check until deadlock_timeout allowing a good reduction in deadlock checks since far few buffer pins are held for that duration. It's worth doing anyway, though major goal is to prevent further reports of context switching with high numbers of users on occasional tests.
Diffstat (limited to 'src/backend/storage/ipc')
-rw-r--r--src/backend/storage/ipc/standby.c42
1 files changed, 15 insertions, 27 deletions
diff --git a/src/backend/storage/ipc/standby.c b/src/backend/storage/ipc/standby.c
index c9d88267b38..204969d3cb8 100644
--- a/src/backend/storage/ipc/standby.c
+++ b/src/backend/storage/ipc/standby.c
@@ -11,7 +11,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/ipc/standby.c,v 1.23 2010/05/14 07:11:49 sriggs Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/ipc/standby.c,v 1.24 2010/05/26 19:52:52 sriggs Exp $
*
*-------------------------------------------------------------------------
*/
@@ -388,12 +388,15 @@ ResolveRecoveryConflictWithBufferPin(void)
}
else if (MaxStandbyDelay < 0)
{
+ TimestampTz now = GetCurrentTimestamp();
+
/*
- * Send out a request to check for buffer pin deadlocks before we
- * wait. This is fairly cheap, so no need to wait for deadlock timeout
- * before trying to send it out.
+ * Set timeout for deadlock check (only)
*/
- SendRecoveryConflictWithBufferPin(PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK);
+ if (enable_standby_sig_alarm(now, now, true))
+ sig_alarm_enabled = true;
+ else
+ elog(FATAL, "could not set timer for process wakeup");
}
else
{
@@ -410,34 +413,19 @@ ResolveRecoveryConflictWithBufferPin(void)
}
else
{
- TimestampTz fin_time; /* Expected wake-up time by timer */
- long timer_delay_secs; /* Amount of time we set timer
- * for */
- int timer_delay_usecs;
-
- /*
- * Send out a request to check for buffer pin deadlocks before we
- * wait. This is fairly cheap, so no need to wait for deadlock
- * timeout before trying to send it out.
- */
- SendRecoveryConflictWithBufferPin(PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK);
+ TimestampTz max_standby_time;
/*
- * How much longer we should wait?
+ * At what point in the future do we hit MaxStandbyDelay?
*/
- fin_time = TimestampTzPlusMilliseconds(then, MaxStandbyDelay);
-
- TimestampDifference(now, fin_time,
- &timer_delay_secs, &timer_delay_usecs);
+ max_standby_time = TimestampTzPlusMilliseconds(then, MaxStandbyDelay);
+ Assert(max_standby_time > now);
/*
- * It's possible that the difference is less than a microsecond;
- * ensure we don't cancel, rather than set, the interrupt.
+ * Wake up at MaxStandby delay, and check for deadlocks as well
+ * if we will be waiting longer than deadlock_timeout
*/
- if (timer_delay_secs == 0 && timer_delay_usecs == 0)
- timer_delay_usecs = 1;
-
- if (enable_standby_sig_alarm(timer_delay_secs, timer_delay_usecs, fin_time))
+ if (enable_standby_sig_alarm(now, max_standby_time, false))
sig_alarm_enabled = true;
else
elog(FATAL, "could not set timer for process wakeup");