PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Jak automatycznie zamykać bezczynne połączenia w PostgreSQL?

Dla zainteresowanych, oto rozwiązanie, które wymyśliłem, zainspirowane komentarzem Craiga Ringera:

(...) użyj zadania cron, aby sprawdzić, kiedy połączenie było ostatnio aktywne (zobacz pg_stat_activity) i użyj pg_terminate_backend, aby zabić stare.(...)

Wybrane rozwiązanie sprowadza się do tego:

  • Najpierw aktualizujemy do Postgresql 9.2.
  • Następnie planujemy uruchamianie wątku co sekundę.
  • Gdy wątek działa, szuka starych nieaktywnych połączeń.
    • Połączenie jest uważane za nieaktywne jeśli jego stan jest albo idle , idle in transaction , idle in transaction (aborted) lub disabled .
    • Połączenie jest uważane za stare jeśli jego stan pozostał taki sam przez ponad 5 minut.
  • Istnieją dodatkowe wątki, które robią to samo, co powyżej. Jednak te wątki łączą się z bazą danych z innym użytkownikiem.
  • Zostawiamy co najmniej jedno połączenie otwarte dla dowolnej aplikacji połączonej z naszą bazą danych. (rank() funkcja)

To jest zapytanie SQL wykonywane przez wątek:

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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Wydajność OLTP od PostgreSQL 8.3

  2. Jak porównać dane między dwiema bazami danych w PostgreSQL?

  3. Używanie puli połączeń PgBouncer dla PostgreSQL z ClusterControl 1.8.2

  4. Django:odmowa uprawnień podczas próby uzyskania dostępu do bazy danych po przywróceniu (migracji)

  5. Rownum w postgresql