aboutsummaryrefslogtreecommitdiff
path: root/src/backend/tcop/postgres.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2021-01-06 18:28:42 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2021-01-06 18:28:52 -0500
commit9877374bef76ef03923f6aa8b955f2dbcbe6c2c7 (patch)
tree9255038d282a07de135530578d5b365a4aaa18dd /src/backend/tcop/postgres.c
parent09cf1d52267644cdbdb734294012cf1228745aaa (diff)
downloadpostgresql-9877374bef76ef03923f6aa8b955f2dbcbe6c2c7.tar.gz
postgresql-9877374bef76ef03923f6aa8b955f2dbcbe6c2c7.zip
Add idle_session_timeout.
This GUC variable works much like idle_in_transaction_session_timeout, in that it kills sessions that have waited too long for a new client query. But it applies when we're not in a transaction, rather than when we are. Li Japin, reviewed by David Johnston and Hayato Kuroda, some fixes by me Discussion: https://postgr.es/m/763A0689-F189-459E-946F-F0EC4458980B@hotmail.com
Diffstat (limited to 'src/backend/tcop/postgres.c')
-rw-r--r--src/backend/tcop/postgres.c48
1 files changed, 41 insertions, 7 deletions
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 9d98c028a2d..2b53ebf97dc 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -3242,14 +3242,28 @@ ProcessInterrupts(void)
if (IdleInTransactionSessionTimeoutPending)
{
- /* Has the timeout setting changed since last we looked? */
+ /*
+ * If the GUC has been reset to zero, ignore the signal. This is
+ * important because the GUC update itself won't disable any pending
+ * interrupt.
+ */
if (IdleInTransactionSessionTimeout > 0)
ereport(FATAL,
(errcode(ERRCODE_IDLE_IN_TRANSACTION_SESSION_TIMEOUT),
errmsg("terminating connection due to idle-in-transaction timeout")));
else
IdleInTransactionSessionTimeoutPending = false;
+ }
+ if (IdleSessionTimeoutPending)
+ {
+ /* As above, ignore the signal if the GUC has been reset to zero. */
+ if (IdleSessionTimeout > 0)
+ ereport(FATAL,
+ (errcode(ERRCODE_IDLE_SESSION_TIMEOUT),
+ errmsg("terminating connection due to idle-session timeout")));
+ else
+ IdleSessionTimeoutPending = false;
}
if (ProcSignalBarrierPending)
@@ -3826,7 +3840,8 @@ PostgresMain(int argc, char *argv[],
StringInfoData input_message;
sigjmp_buf local_sigjmp_buf;
volatile bool send_ready_for_query = true;
- bool disable_idle_in_transaction_timeout = false;
+ bool idle_in_transaction_timeout_enabled = false;
+ bool idle_session_timeout_enabled = false;
/* Initialize startup process environment if necessary. */
if (!IsUnderPostmaster)
@@ -4228,6 +4243,8 @@ PostgresMain(int argc, char *argv[],
* processing of batched messages, and because we don't want to report
* uncommitted updates (that confuses autovacuum). The notification
* processor wants a call too, if we are not in a transaction block.
+ *
+ * Also, if an idle timeout is enabled, start the timer for that.
*/
if (send_ready_for_query)
{
@@ -4239,7 +4256,7 @@ PostgresMain(int argc, char *argv[],
/* Start the idle-in-transaction timer */
if (IdleInTransactionSessionTimeout > 0)
{
- disable_idle_in_transaction_timeout = true;
+ idle_in_transaction_timeout_enabled = true;
enable_timeout_after(IDLE_IN_TRANSACTION_SESSION_TIMEOUT,
IdleInTransactionSessionTimeout);
}
@@ -4252,7 +4269,7 @@ PostgresMain(int argc, char *argv[],
/* Start the idle-in-transaction timer */
if (IdleInTransactionSessionTimeout > 0)
{
- disable_idle_in_transaction_timeout = true;
+ idle_in_transaction_timeout_enabled = true;
enable_timeout_after(IDLE_IN_TRANSACTION_SESSION_TIMEOUT,
IdleInTransactionSessionTimeout);
}
@@ -4275,6 +4292,14 @@ PostgresMain(int argc, char *argv[],
set_ps_display("idle");
pgstat_report_activity(STATE_IDLE, NULL);
+
+ /* Start the idle-session timer */
+ if (IdleSessionTimeout > 0)
+ {
+ idle_session_timeout_enabled = true;
+ enable_timeout_after(IDLE_SESSION_TIMEOUT,
+ IdleSessionTimeout);
+ }
}
/* Report any recently-changed GUC options */
@@ -4310,12 +4335,21 @@ PostgresMain(int argc, char *argv[],
DoingCommandRead = false;
/*
- * (5) turn off the idle-in-transaction timeout
+ * (5) turn off the idle-in-transaction and idle-session timeouts, if
+ * active.
+ *
+ * At most one of these two will be active, so there's no need to
+ * worry about combining the timeout.c calls into one.
*/
- if (disable_idle_in_transaction_timeout)
+ if (idle_in_transaction_timeout_enabled)
{
disable_timeout(IDLE_IN_TRANSACTION_SESSION_TIMEOUT, false);
- disable_idle_in_transaction_timeout = false;
+ idle_in_transaction_timeout_enabled = false;
+ }
+ if (idle_session_timeout_enabled)
+ {
+ disable_timeout(IDLE_SESSION_TIMEOUT, false);
+ idle_session_timeout_enabled = false;
}
/*