Some clients connect to our postgresql database but leave the connections opened. Is it possible to tell Postgresql to close those connection after a certain amount of inactivity ?
TL;DR
IF you're using a Postgresql version >=
9.2
THEN use the solution I came up withIF you don't want to write any code
THEN use arqnid's solutionIF you don't want to write any code
AND you're using a Postgresql version >=14
THEN use Laurenz Albe's solution
How to kill all other active connections to your database in PostgreSQL? Using SQL Query, run the query below: SELECT pg_terminate_backend(pg_stat_activity. pid) FROM pg_stat_activity WHERE pg_stat_activity.
No, something akin to the other answers is required for previous versions. SET SESSION is just for the current session (it will go back to the default once you open a new connection).
idle: This indicates that the connection is idle and we need to track these connections based on the time that they have been idle. idle in transaction: This indicates the backend is in a transaction, but it is currently not doing anything and could be waiting for an input from the end user.
If you want to see how many idle connections you have that have an open transaction, you could use: select * from pg_stat_activity where (state = 'idle in transaction') and xact_start is not null; This will provide a list of open connections that are in the idle state, that also have an open transaction.
For those who are interested, here is the solution I came up with, inspired from Craig Ringer's comment:
(...) use a cron job to look at when the connection was last active (see pg_stat_activity) and use pg_terminate_backend to kill old ones.(...)
The chosen solution comes down like this:
- A connection is considered inactive if its state is either
idle
,idle in transaction
,idle in transaction (aborted)
ordisabled
.- A connection is considered old if its state stayed the same during more than 5 minutes.
rank()
function)This is the SQL query run by the thread:
WITH inactive_connections AS ( SELECT pid, rank() over (partition by client_addr order by backend_start ASC) as rank FROM pg_stat_activity WHERE -- Exclude the thread owned connection (ie no auto-kill) pid <> pg_backend_pid( ) AND -- Exclude known applications connections application_name !~ '(?:psql)|(?:pgAdmin.+)' AND -- Include connections to the same database the thread is connected to datname = current_database() AND -- Include connections using the same thread username connection usename = current_user AND -- Include inactive connections only state in ('idle', 'idle in transaction', 'idle in transaction (aborted)', 'disabled') AND -- Include old connections (found with the state_change field) current_timestamp - state_change > interval '5 minutes' ) SELECT pg_terminate_backend(pid) FROM inactive_connections WHERE rank > 1 -- Leave one connection for each application connected to the database
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With