aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/async.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2004-05-23 03:50:45 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2004-05-23 03:50:45 +0000
commitebfc56d3fb41d914c799555a1f4c9d1a72379e9f (patch)
tree7fb674efed5b26eb9a11b0e77733b2c8e7eaf642 /src/backend/commands/async.c
parent4d86ae42600c42834a55371630416e98593b7b11 (diff)
downloadpostgresql-ebfc56d3fb41d914c799555a1f4c9d1a72379e9f.tar.gz
postgresql-ebfc56d3fb41d914c799555a1f4c9d1a72379e9f.zip
Handle impending sinval queue overflow by means of a separate signal
(SIGUSR1, which we have not been using recently) instead of piggybacking on SIGUSR2-driven NOTIFY processing. This has several good results: the processing needed to drain the sinval queue is a lot less than the processing needed to answer a NOTIFY; there's less contention since we don't have a bunch of backends all trying to acquire exclusive lock on pg_listener; backends that are sitting inside a transaction block can still drain the queue, whereas NOTIFY processing can't run if there's an open transaction block. (This last is a fairly serious issue that I don't think we ever recognized before --- with clients like JDBC that tend to sit with open transaction blocks, the sinval queue draining mechanism never really worked as intended, probably resulting in a lot of useless cache-reset overhead.) This is the last of several proposed changes in response to Philip Warner's recent report of sinval-induced performance problems.
Diffstat (limited to 'src/backend/commands/async.c')
-rw-r--r--src/backend/commands/async.c34
1 files changed, 23 insertions, 11 deletions
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index 5233e781789..15d7c0aae5c 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/async.c,v 1.110 2004/05/22 21:58:24 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/async.c,v 1.111 2004/05/23 03:50:45 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -86,6 +86,7 @@
#include "libpq/pqformat.h"
#include "miscadmin.h"
#include "storage/ipc.h"
+#include "storage/sinval.h"
#include "tcop/tcopprot.h"
#include "utils/fmgroids.h"
#include "utils/ps_status.h"
@@ -607,7 +608,7 @@ AtAbort_Notify(void)
/*
*--------------------------------------------------------------
- * Async_NotifyHandler
+ * NotifyInterruptHandler
*
* This is the signal handler for SIGUSR2.
*
@@ -623,7 +624,7 @@ AtAbort_Notify(void)
*--------------------------------------------------------------
*/
void
-Async_NotifyHandler(SIGNAL_ARGS)
+NotifyInterruptHandler(SIGNAL_ARGS)
{
int save_errno = errno;
@@ -669,12 +670,12 @@ Async_NotifyHandler(SIGNAL_ARGS)
{
/* Here, it is finally safe to do stuff. */
if (Trace_notify)
- elog(DEBUG1, "Async_NotifyHandler: perform async notify");
+ elog(DEBUG1, "NotifyInterruptHandler: perform async notify");
ProcessIncomingNotify();
if (Trace_notify)
- elog(DEBUG1, "Async_NotifyHandler: done");
+ elog(DEBUG1, "NotifyInterruptHandler: done");
}
}
@@ -766,12 +767,20 @@ EnableNotifyInterrupt(void)
* This is called by the PostgresMain main loop just after receiving
* a frontend command. Signal handler execution of inbound notifies
* is disabled until the next EnableNotifyInterrupt call.
+ *
+ * The SIGUSR1 signal handler also needs to call this, so as to
+ * prevent conflicts if one signal interrupts the other. So we
+ * must return the previous state of the flag.
* --------------------------------------------------------------
*/
-void
+bool
DisableNotifyInterrupt(void)
{
+ bool result = (notifyInterruptEnabled != 0);
+
notifyInterruptEnabled = 0;
+
+ return result;
}
/*
@@ -785,10 +794,6 @@ DisableNotifyInterrupt(void)
* and clear the notification field in pg_listener until next time.
*
* NOTE: since we are outside any transaction, we must create our own.
- *
- * Results:
- * XXX
- *
* --------------------------------------------------------------
*/
static void
@@ -803,11 +808,15 @@ ProcessIncomingNotify(void)
Datum value[Natts_pg_listener];
char repl[Natts_pg_listener],
nulls[Natts_pg_listener];
+ bool catchup_enabled;
+
+ /* Must prevent SIGUSR1 interrupt while I am running */
+ catchup_enabled = DisableCatchupInterrupt();
if (Trace_notify)
elog(DEBUG1, "ProcessIncomingNotify");
- set_ps_display("async_notify");
+ set_ps_display("notify interrupt");
notifyInterruptOccurred = 0;
@@ -883,6 +892,9 @@ ProcessIncomingNotify(void)
if (Trace_notify)
elog(DEBUG1, "ProcessIncomingNotify: done");
+
+ if (catchup_enabled)
+ EnableCatchupInterrupt();
}
/*