2012-09-12 13 views
26

कुछ ग्राहक हमारे पोस्टग्रेस्क्ल डेटाबेस से कनेक्ट होते हैं लेकिन कनेक्शन खोले जाते हैं। क्या पोस्टग्रेस्क्ल को कुछ निश्चित निष्क्रियता के बाद उन कनेक्शन को बंद करना संभव है?स्वचालित रूप से PostgreSQL में निष्क्रिय कनेक्शन कैसे बंद करें?

टी एल; डॉ

आप एक Postgresql संस्करण उपयोग कर रहे हैं> = 9.2
तो the solution I came up with

उपयोग करें यदि आप किसी भी कोड लिखने के लिए नहीं करना चाहती
तब का उपयोग arqnid's solution

+2

आप एक क्रॉन जॉब का उपयोग पर जब कनेक्शन पिछले सक्रिय था देखने के लिए कर सकता है ('देख pg_stat_activity') और उपयोग' पुराने लोगों को मारने के लिए pg_terminate_backend'। आसानी से एक साधारण क्वेरी में व्यक्त किया। मुझे यकीन नहीं है कि 'pg_terminate_backend' सुंदर-प्राचीन 8.3 में उपलब्ध था, हालांकि। –

उत्तर

27

जो लोग रुचि रखते हैं के लिए, यहाँ समाधान मैं के साथ आया था, Craig Ringer की टिप्पणी से प्रेरित है:

(...) एक क्रॉन जॉब का उपयोग पर जब कनेक्शन अंतिम बार देखने के लिए सक्रिय (pg_stat_activity देखें) और pg_terminate_backend का उपयोग पुराने लोगों को मारने के लिए (...)

चुना समाधान इस तरह नीचे आता है:।

  • सबसे पहले, हम Postgresql 9.2 में अपग्रेड करते हैं।
  • फिर, हम प्रत्येक सेकेंड को चलाने के लिए थ्रेड शेड्यूल करते हैं।
  • जब थ्रेड चलता है, तो यह किसी भी पुराने निष्क्रिय कनेक्शन की तलाश करता है।
    • एक कनेक्शन माना जाता है निष्क्रिय अगर इसकी राज्य या तो idle, idle in transaction, idle in transaction (aborted) या disabled है।
    • एक कनेक्शन पुराना माना जाता है यदि इसकी अंतिम स्थिति 5 मिनट से अधिक समय के लिए बदल गई है।
  • अतिरिक्त धागे जो ऊपर जैसा ही करते हैं। हालांकि, वे थ्रेड अलग-अलग उपयोगकर्ता के साथ डेटाबेस से कनेक्ट होते हैं।
  • हम अपने डेटाबेस से जुड़े किसी भी एप्लिकेशन के लिए कम से कम एक कनेक्शन खोलते हैं। (rank() समारोह)

यह एसक्यूएल धागा द्वारा चलाए जा क्वेरी है:

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

अंत में, हम 'pg_terminate_backend' का लाभ उठाने के लिए पोस्टग्रेस्क्ल 9.2 पर चले गए। हमने समय-समय पर 'pg_terminate_backend' का आह्वान करने के लिए नौकरी की तरह एक क्रॉन का उपयोग किया। – Stephan

+0

क्या आप एक स्क्रिप्ट पोस्ट कर सकते हैं जिसका आप उपयोग करते हैं? – Andrus

+0

@Andrus मेरे उत्तर में अपडेट देखें। – Stephan

10

PgBouncer जैसे प्रॉक्सी से कनेक्ट करें जो server_idle_timeout सेकंड के बाद कनेक्शन बंद कर देगा।

+0

क्या पीजी पूल II वही कर सकता है? – wolf97084

+0

@ wolf97084 यह उत्तर देखें: http: // stackoverflow।कॉम/ए/30769511/363573 – Stephan

+0

@ स्टीफन धन्यवाद! अगर आपने टिप्पणी में मुझे टैग नहीं किया है तो मुझे जवाब याद आएगा। – wolf97084

संबंधित मुद्दे