sql >> Databasteknik >  >> RDS >> PostgreSQL

Hur stänger man inaktiva anslutningar i PostgreSQL automatiskt?

För den som är intresserad, här är lösningen jag kom fram till, inspirerad av Craig Ringers kommentar:

(...) använd ett cron-jobb för att titta på när anslutningen senast var aktiv (se pg_stat_activity) och använd pg_terminate_backend för att döda gamla.(...)

Den valda lösningen ser ut så här:

  • Först uppgraderar vi till Postgresql 9.2.
  • Då schemalägger vi en tråd som ska köras varje sekund.
  • När tråden körs letar den efter gamla inaktiva anslutningar.
    • En anslutning anses vara inaktiv om dess tillstånd är antingen idle , idle in transaction , idle in transaction (aborted) eller disabled .
    • En anslutning anses vara gammal om dess tillstånd förblev densamma under mer än 5 minuter.
  • Det finns ytterligare trådar som gör samma sak som ovan. Men dessa trådar ansluter till databasen med en annan användare.
  • Vi lämnar minst en anslutning öppen för alla program som är anslutna till vår databas. (rank() funktion)

Det här är SQL-frågan som körs av tråden:

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


  1. MySQL MED klausul

  2. Hur skapar man materialiserade vyer i SQL Server?

  3. Hitta förälder rekursivt med Query

  4. Hur man släpper bordet i oracle