v3-0001-Allow-terminating-the-idle-sessions.patch
application/octet-stream
Filename: v3-0001-Allow-terminating-the-idle-sessions.patch
Type: application/octet-stream
Part: 0
Message:
Re: Terminate the idle sessions
Patch
Format: format-patch
Series: patch v3-0001
Subject: Allow terminating the idle sessions
| File | + | − |
|---|---|---|
| doc/src/sgml/config.sgml | 17 | 0 |
| src/backend/storage/lmgr/proc.c | 1 | 0 |
| src/backend/tcop/postgres.c | 25 | 0 |
| src/backend/utils/errcodes.txt | 1 | 0 |
| src/backend/utils/init/globals.c | 1 | 0 |
| src/backend/utils/init/postinit.c | 10 | 0 |
| src/backend/utils/misc/guc.c | 11 | 0 |
| src/backend/utils/misc/postgresql.conf.sample | 1 | 0 |
| src/include/miscadmin.h | 1 | 0 |
| src/include/storage/proc.h | 1 | 0 |
| src/include/utils/timeout.h | 1 | 0 |
From 4487dd40a67af5338fa60708f6975b3da1588ba7 Mon Sep 17 00:00:00 2001
From: Japin <jianping.li@ww-it.cn>
Date: Tue, 11 Aug 2020 10:52:14 +0800
Subject: [PATCH v3 1/2] Allow terminating the idle sessions
---
doc/src/sgml/config.sgml | 17 +++++++++++++
src/backend/storage/lmgr/proc.c | 1 +
src/backend/tcop/postgres.c | 25 +++++++++++++++++++
src/backend/utils/errcodes.txt | 1 +
src/backend/utils/init/globals.c | 1 +
src/backend/utils/init/postinit.c | 10 ++++++++
src/backend/utils/misc/guc.c | 11 ++++++++
src/backend/utils/misc/postgresql.conf.sample | 1 +
src/include/miscadmin.h | 1 +
src/include/storage/proc.h | 1 +
src/include/utils/timeout.h | 1 +
11 files changed, 70 insertions(+)
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 7a7177c550..3a08fc3859 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -8185,6 +8185,23 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
</listitem>
</varlistentry>
+ <varlistentry id="guc-idle-session-timeout" xreflabel="idle_session_timeout">
+ <term><varname>idle_session_timeout</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>idle_session_timeout</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Terminate any session that has been idle for longer than the specified amount of time.
+ </para>
+ <para>
+ If this value is specified without units, it is taken as milliseconds.
+ A value of zero (the default) disables the timeout.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry id="guc-idle-in-transaction-session-timeout" xreflabel="idle_in_transaction_session_timeout">
<term><varname>idle_in_transaction_session_timeout</varname> (<type>integer</type>)
<indexterm>
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index aa9fbd8054..7fe3ca1a39 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -60,6 +60,7 @@
int DeadlockTimeout = 1000;
int StatementTimeout = 0;
int LockTimeout = 0;
+int IdleSessionTimeout = 0;
int IdleInTransactionSessionTimeout = 0;
bool log_lock_waits = false;
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index c9424f167c..15c21bc4fe 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -3204,6 +3204,16 @@ ProcessInterrupts(void)
}
+ if (IdleSessionTimeoutPending)
+ {
+ if (IdleSessionTimeout > 0)
+ ereport(FATAL,
+ (errcode(ERRCODE_IDLE_SESSION_TIMEOUT),
+ errmsg("terminating connection due to idle-session timeout")));
+ else
+ IdleSessionTimeoutPending = false;
+ }
+
if (ProcSignalBarrierPending)
ProcessProcSignalBarrier();
@@ -3783,6 +3793,7 @@ PostgresMain(int argc, char *argv[],
sigjmp_buf local_sigjmp_buf;
volatile bool send_ready_for_query = true;
bool disable_idle_in_transaction_timeout = false;
+ bool disable_idle_session_timeout = false;
/* Initialize startup process environment if necessary. */
if (!IsUnderPostmaster)
@@ -4237,6 +4248,14 @@ PostgresMain(int argc, char *argv[],
set_ps_display("idle");
pgstat_report_activity(STATE_IDLE, NULL);
+
+ /* Start the idle-session timer */
+ if (IdleSessionTimeout > 0)
+ {
+ disable_idle_session_timeout = true;
+ enable_timeout_after(IDLE_SESSION_TIMEOUT,
+ IdleSessionTimeout);
+ }
}
ReadyForQuery(whereToSendOutput);
@@ -4277,6 +4296,12 @@ PostgresMain(int argc, char *argv[],
disable_idle_in_transaction_timeout = false;
}
+ if (disable_idle_session_timeout)
+ {
+ disable_timeout(IDLE_SESSION_TIMEOUT, false);
+ disable_idle_session_timeout = false;
+ }
+
/*
* (6) check for any other interesting events that happened while we
* slept.
diff --git a/src/backend/utils/errcodes.txt b/src/backend/utils/errcodes.txt
index c79312ed03..d5935a2ca9 100644
--- a/src/backend/utils/errcodes.txt
+++ b/src/backend/utils/errcodes.txt
@@ -109,6 +109,7 @@ Section: Class 08 - Connection Exception
08004 E ERRCODE_SQLSERVER_REJECTED_ESTABLISHMENT_OF_SQLCONNECTION sqlserver_rejected_establishment_of_sqlconnection
08007 E ERRCODE_TRANSACTION_RESOLUTION_UNKNOWN transaction_resolution_unknown
08P01 E ERRCODE_PROTOCOL_VIOLATION protocol_violation
+08008 E ERRCODE_IDLE_SESSION_TIMEOUT idle_session_timeout
Section: Class 09 - Triggered Action Exception
diff --git a/src/backend/utils/init/globals.c b/src/backend/utils/init/globals.c
index 6ab8216839..03bfd88d2c 100644
--- a/src/backend/utils/init/globals.c
+++ b/src/backend/utils/init/globals.c
@@ -31,6 +31,7 @@ volatile sig_atomic_t InterruptPending = false;
volatile sig_atomic_t QueryCancelPending = false;
volatile sig_atomic_t ProcDiePending = false;
volatile sig_atomic_t ClientConnectionLost = false;
+volatile sig_atomic_t IdleSessionTimeoutPending = false;
volatile sig_atomic_t IdleInTransactionSessionTimeoutPending = false;
volatile sig_atomic_t ProcSignalBarrierPending = false;
volatile uint32 InterruptHoldoffCount = 0;
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index d4ab4c7e23..5c88c4cfff 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -72,6 +72,7 @@ static void InitCommunication(void);
static void ShutdownPostgres(int code, Datum arg);
static void StatementTimeoutHandler(void);
static void LockTimeoutHandler(void);
+static void IdleSessionTimeoutHandler(void);
static void IdleInTransactionSessionTimeoutHandler(void);
static bool ThereIsAtLeastOneRole(void);
static void process_startup_options(Port *port, bool am_superuser);
@@ -629,6 +630,7 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username,
RegisterTimeout(DEADLOCK_TIMEOUT, CheckDeadLockAlert);
RegisterTimeout(STATEMENT_TIMEOUT, StatementTimeoutHandler);
RegisterTimeout(LOCK_TIMEOUT, LockTimeoutHandler);
+ RegisterTimeout(IDLE_SESSION_TIMEOUT, IdleSessionTimeoutHandler);
RegisterTimeout(IDLE_IN_TRANSACTION_SESSION_TIMEOUT,
IdleInTransactionSessionTimeoutHandler);
}
@@ -1237,6 +1239,14 @@ LockTimeoutHandler(void)
kill(MyProcPid, SIGINT);
}
+static void
+IdleSessionTimeoutHandler(void)
+{
+ IdleSessionTimeoutPending = true;
+ InterruptPending = true;
+ SetLatch(MyLatch);
+}
+
static void
IdleInTransactionSessionTimeoutHandler(void)
{
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index de87ad6ef7..cd81177c4f 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -2503,6 +2503,17 @@ static struct config_int ConfigureNamesInt[] =
NULL, NULL, NULL
},
+ {
+ {"idle_session_timeout", PGC_USERSET, CLIENT_CONN_STATEMENT,
+ gettext_noop("Sets the maximum allowed duration of any idling session."),
+ gettext_noop("A value of 0 turns off the timeout."),
+ GUC_UNIT_MS
+ },
+ &IdleSessionTimeout,
+ 0, 0, INT_MAX,
+ NULL, NULL, NULL
+ },
+
{
{"idle_in_transaction_session_timeout", PGC_USERSET, CLIENT_CONN_STATEMENT,
gettext_noop("Sets the maximum allowed duration of any idling transaction."),
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
index 9cb571f7cc..6e3f14f234 100644
--- a/src/backend/utils/misc/postgresql.conf.sample
+++ b/src/backend/utils/misc/postgresql.conf.sample
@@ -664,6 +664,7 @@
#statement_timeout = 0 # in milliseconds, 0 is disabled
#lock_timeout = 0 # in milliseconds, 0 is disabled
#idle_in_transaction_session_timeout = 0 # in milliseconds, 0 is disabled
+#idle_session_timeout = 0 # in milliseconds, 0 is disabled
#vacuum_freeze_min_age = 50000000
#vacuum_freeze_table_age = 150000000
#vacuum_multixact_freeze_min_age = 5000000
diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h
index 72e3352398..995b603899 100644
--- a/src/include/miscadmin.h
+++ b/src/include/miscadmin.h
@@ -81,6 +81,7 @@
extern PGDLLIMPORT volatile sig_atomic_t InterruptPending;
extern PGDLLIMPORT volatile sig_atomic_t QueryCancelPending;
extern PGDLLIMPORT volatile sig_atomic_t ProcDiePending;
+extern PGDLLIMPORT volatile sig_atomic_t IdleSessionTimeoutPending;
extern PGDLLIMPORT volatile sig_atomic_t IdleInTransactionSessionTimeoutPending;
extern PGDLLIMPORT volatile sig_atomic_t ProcSignalBarrierPending;
diff --git a/src/include/storage/proc.h b/src/include/storage/proc.h
index 9c9a50ae45..a0ccabe3ec 100644
--- a/src/include/storage/proc.h
+++ b/src/include/storage/proc.h
@@ -368,6 +368,7 @@ extern PGPROC *PreparedXactProcs;
extern PGDLLIMPORT int DeadlockTimeout;
extern PGDLLIMPORT int StatementTimeout;
extern PGDLLIMPORT int LockTimeout;
+extern PGDLLIMPORT int IdleSessionTimeout;
extern PGDLLIMPORT int IdleInTransactionSessionTimeout;
extern bool log_lock_waits;
diff --git a/src/include/utils/timeout.h b/src/include/utils/timeout.h
index 83a15f6795..6be398c983 100644
--- a/src/include/utils/timeout.h
+++ b/src/include/utils/timeout.h
@@ -30,6 +30,7 @@ typedef enum TimeoutId
STANDBY_DEADLOCK_TIMEOUT,
STANDBY_TIMEOUT,
STANDBY_LOCK_TIMEOUT,
+ IDLE_SESSION_TIMEOUT,
IDLE_IN_TRANSACTION_SESSION_TIMEOUT,
/* First user-definable timeout reason */
USER_TIMEOUT,
--
2.28.0