1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-17 17:02:08 +03:00

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
This commit is contained in:
Tom Lane
2021-01-06 18:28:42 -05:00
parent 09cf1d5226
commit 9877374bef
11 changed files with 115 additions and 16 deletions

View File

@ -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;
}
/*