2012-09-12 57 views
26

某些客戶端連接到我們的postgresql數據庫,但保持連接打開。 是否可以告訴Postgresql在一定數量的不活動之後關閉這些連接?如何自動關閉PostgreSQL中的空閒連接?

TL; DR

如果您使用PostgreSQL的版本> = 9.2
然後用the solution I came up with

如果你不想寫任何代碼
然後使用arqnid's solution

+2

你可以使用cron作業來看看,當連接上一個活動(見'pg_stat_activity')和使用' pg_terminate_backend'來殺死舊的。以簡單的查詢輕鬆表達。不過,我不確定'pg_terminate_backend'在古老的8.3中是否可用。 –

回答

27

對於那些有興趣誰,這裏是我想出了一個解決方案,從Craig Ringer的評論的啓發:

(...)使用cron作業來看看當連接最後有效(見和pg_stat_activity),並使用pg_terminate_backend殺死舊的(...)

選擇的解決方案可以歸結如下:。

  • 首先,我們升級到Postgresql 9.2。
  • 然後,我們安排一個線程每秒運行一次。
  • 當線程運行時,它會查找任何舊的非活動連接。
    • 的連接被認爲是不活動的如果狀態要麼idleidle in transactionidle in transaction (aborted)disabled
    • 連接被認爲是如果其最後狀態已經改變超過5分鐘。
  • 還有其他線程與上面相同。但是,這些線程以不同的用戶連接到數據庫。
  • 我們至少爲連接到我們數據庫的任何應用程序打開一個連接。 (rank()功能)

這是SQL查詢在線程中運行:

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 
+0

最後,我們轉到Postgresql 9.2以獲得'pg_terminate_backend'的優勢。我們使用了一個類似cron的工作來定期調用'pg_terminate_backend'。 – Stephan

+0

你可以發表你使用的腳本嗎? – Andrus

+0

@Andrus查看我答案中的更新。 – Stephan

10

通過代理連接,如PgBouncer,這將在server_idle_timeout秒後關閉連接。

+0

可以pg pool II做同樣的事嗎? – wolf97084

+0

@ wolf97084看到這個答案:http:// stackoverflow。com/a/30769511/363573 – Stephan

+0

@Stephan謝謝!如果你沒有在評論中標記我,我會想念答案。 – wolf97084