वहाँ निष्क्रिय PostgreSQL कनेक्शन के लिए एक समय सीमा है?


94
1 S postgres  5038   876  0  80   0 - 11962 sk_wai 09:57 ?        00:00:00 postgres: postgres my_app ::1(45035) idle                                                                                 
1 S postgres  9796   876  0  80   0 - 11964 sk_wai 11:01 ?        00:00:00 postgres: postgres my_app ::1(43084) idle             

मैं उनमें से बहुत कुछ देखता हूं। हम अपने कनेक्शन लीक को ठीक करने की कोशिश कर रहे हैं। लेकिन इस बीच, हम इन निष्क्रिय कनेक्शन के लिए एक समय सीमा निर्धारित करना चाहते हैं, शायद अधिकतम 5 मिनट तक।


आप डीबी से कैसे जुड़ रहे हैं? सॉकेट टाइमआउट वह हो सकता है जिसे आप ढूंढ रहे हैं।
दून

हमारे पास यह विरासत Pylons वेब ऐप है, और हमने SQLAlchemy का उपयोग किया है, लेकिन जाहिर है कि हमने इसे ठीक से उपयोग नहीं किया। मुझे याद नहीं है। हम लीक को ठीक करने की कोशिश कर रहे हैं। socketTimeoutडॉक्टर से ऐसा लगता है कि यह डीबी से पूरी तरह से जुड़ा हुआ है। मैं प्रत्येक बेकार को बंद करने की कोशिश कर रहा हूं, और कनेक्शन स्थापित होते ही काउंटर शुरू हो जाता है।
user1012451


@ user1012451 जब आप कहते हैं "प्रत्येक निष्क्रिय को बंद करें" - क्या आपका मतलब <IDLE> in transactionसत्र समाप्त करना है , लेकिन सत्र चल रहा है लेकिन <IDLE>राज्य में है? दूसरे शब्दों में, लेनदेन समाप्त करें लेकिन सत्र नहीं? (डाउनवॉट: अस्पष्ट प्रश्न)
क्रेग रिंगर

@ क्रेगिंगर कुछ समय बाद, हम अधिकतम क्लाइंट कनेक्शन तक पहुंचते हैं। इसे हल करने के लिए, हमें वेबएप को पुनः आरंभ करना होगा, जो पोस्टग्रैसेकल को पुनः आरंभ करने के लिए बाध्य करता है। जो हर कनेक्शन को मिटा देता है। जब हम इन्हें idleहमेशा के लिए देखते हैं , तो हम पूछ रहे हैं कि क्या हम प्रत्येक कनेक्शन / सत्र पर टाइमआउट सेट कर सकते हैं (मैं ईमानदारी से सही शब्दावली नहीं जानता, क्षमा करें)। यदि किसी सामान्य वेब ऐप के लिए लेनदेन में 5 मिनट लगते हैं तो कुछ गलत होना चाहिए ....
user1012451

जवाबों:


118

ऐसा लगता है कि आपके आवेदन में कनेक्शन लीक है क्योंकि यह पूल किए गए कनेक्शन को बंद करने में विफल रहता है । आपके पास <idle> in transactionसत्रों के साथ समस्याएँ नहीं हैं , लेकिन कुल मिलाकर बहुत सारे कनेक्शन हैं।

कनेक्शन को मारना उसके लिए सही उत्तर नहीं है, लेकिन यह एक अस्थायी ईश अस्थायी अस्थायी है।

PostgreSQL डेटाबेस से अन्य सभी कनेक्शनों को बूट करने के लिए PostgreSQL को फिर से शुरू करने के बजाय, देखें: मैं पोस्टग्रेज डेटाबेस से अन्य सभी उपयोगकर्ताओं को कैसे अलग करूं? और कैसे एक PostgreSQL डेटाबेस को ड्रॉप करने के लिए अगर वहाँ सक्रिय कनेक्शन हैं? । बाद वाला बेहतर क्वेरी दिखाता है।

टाइमआउट सेट करने के लिए, जैसा कि @ डून ने सुझाव दिया है कि पोस्टग्रेक्सेल में स्वचालित रूप से निष्क्रिय कनेक्शन कैसे बंद करें? , जो आपको PostgreSQL के लिए प्रॉक्सी से PgBouncer का उपयोग करने और निष्क्रिय कनेक्शन प्रबंधित करने की सलाह देता है। यह एक बहुत अच्छा विचार है अगर आपके पास एक छोटी गाड़ी का आवेदन है जो वैसे भी कनेक्शन लीक करता है; मैं बहुत दृढ़ता से PgBouncer को कॉन्फ़िगर करने की सलाह देता हूं।

एक टीसीपी रखनेवाला यहाँ काम नहीं करेगा, क्योंकि ऐप अभी भी जुड़ा हुआ है और जीवित है, बस यह नहीं होना चाहिए।

PostgreSQL 9.2 और इसके बाद के संस्करण में, आप नए state_changeटाइमस्टैम्प कॉलम और निष्क्रिय कनेक्शन रीपर को लागू करने के stateक्षेत्र का उपयोग कर सकते हैं pg_stat_activity। क्रॉन जॉब कुछ इस तरह से चलाएं:

SELECT pg_terminate_backend(pid)
    FROM pg_stat_activity
    WHERE datname = 'regress'
      AND pid <> pg_backend_pid()
      AND state = 'idle'
      AND state_change < current_timestamp - INTERVAL '5' MINUTE;

पुराने संस्करणों में आपको जटिल योजनाओं को लागू करने की आवश्यकता होती है जो कनेक्शन के निष्क्रिय होने पर नज़र रखते हैं। भेजा मत खा; बस pgbouncer का उपयोग करें।


4
अच्छा है, लेकिन यह अन्य PgAdmin बैकेंड को मार देगा। अतिरिक्त शर्त application_name = '' का उपयोग करें
एंड्रयू सेलिवानोव

1
क्या मैं pg_terminate_backend चला सकता हूँ अगर मैं pgbouncer का उपयोग कर रहा हूँ?
हेन्ले चिउ

@HenleyChiu मैं नहीं देखता कि क्यों नहीं, हालांकि मैंने विशेष रूप से जाँच नहीं की है।
क्रेग रिंगर

1
ऐसा लगता है कि मेरी वाल भेजने की प्रक्रिया को मार दिया गया है
जोसेफ फारसी

@ क्रेगिंगर यहां तक ​​कि एक psll कनेक्शन को निष्क्रिय कनेक्शन माना जाता है। और किसी को पहले स्थान पर निष्क्रिय कनेक्शन को बंद क्यों करना पड़ता है। मेरे पास एक लंबा चलने वाला कोड है जो pg के साथ संबंध स्थापित करता है कुछ dml ऑपरेशन करता है और फिर कतार पर संदेश के लिए प्रतीक्षा करता है और फिर कुछ और dml कार्रवाई करता है। अब उस अवधि के दौरान अर्थात जब यह कतार के लिए प्रतीक्षा कर रहा है (संदेश के लिए) जैसा कि ऊपर उल्लेख किया गया है तब भी डाक के साथ संबंध है idle। मैं इसे बंद क्यों करूं।
विरेन

72

PostgreSQL 9.6 में, एक नया विकल्प है idle_in_transaction_session_timeoutजो आपको जो वर्णन करता है उसे पूरा करना चाहिए। आप इसे SETकमांड का उपयोग करके सेट कर सकते हैं , जैसे:

SET SESSION idle_in_transaction_session_timeout = '5min';

1
यह इतना सरल है, लेकिन मैं डेटाबेस में बिल्कुल नया हूँ, लेकिन आप इस फ़ंक्शन का उपयोग करने का एक बहुत ही बुनियादी उदाहरण दे सकते हैं?
sg

PostgreSQL के पिछले संस्करणों में ऐसा कुछ भी ??
sdsc81

नहीं, पिछले संस्करणों के लिए अन्य उत्तरों के लिए कुछ आवश्यक है।
शोस्ती

क्या आपको डेटाबेस के प्रत्येक पुनरारंभ पर इस पैरामीटर को सेट करने की आवश्यकता है? या एक बार करने के बाद आप भूल सकते हैं? धन्यवाद
फ्रेस्को

5
SET SESSIONबस वर्तमान सत्र के लिए है (नया कनेक्शन खोलने के बाद यह डिफ़ॉल्ट पर वापस जाएगा)। आप उदाहरण के लिए ALTER DATABASE SET idle_in_transaction_session_timeout = '5min', या कॉन्फ़िगरेशन फ़ाइलों का उपयोग करके डेटाबेस स्तर पर कॉन्फ़िगरेशन पैरामीटर भी सेट कर सकते हैं (देखें postgresql.org/docs/current/static/config-setting.html )।
shosti

22

PostgreSQL 9.1 में, निम्नलिखित क्वेरी के साथ निष्क्रिय कनेक्शन। इसने मुझे उस स्थिति से दूर करने में मदद की जो डेटाबेस को फिर से शुरू करने में वारंट की थी। यह ज्यादातर JDBC कनेक्शन के खुलने और ठीक से बंद न होने के साथ होता है।

SELECT
   pg_terminate_backend(procpid)
FROM
   pg_stat_activity
WHERE
   current_query = '<IDLE>'
AND
   now() - query_start > '00:10:00';

1
pg_terminate_backend 8.4 में से है
एंड्रयू बैंक्स

8

यदि आप 9.6+ पोस्टग्रैस्कल का उपयोग कर रहे हैं, तो अपने पोस्टग्रैक्कल.कॉन्फ़ में आप सेट कर सकते हैं

idle_in_transaction_session_timeout = 30000 (Msec)


0

एक संभावित वर्कअराउंड जो बाहरी शेड्यूल किए गए कार्य के बिना डेटाबेस सत्र टाइमआउट को सक्षम करने के लिए है, जो कि मैंने विकसित किया है एक्सटेंशन pg_timeout का उपयोग करना है ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.