अतिथि लेखक:माइकल जे स्वार्ट (@MJSwart)
हम हाल ही में हमारे द्वारा फेंके गए कई अपवादों से हैरान थे। SqlConnection खोलने का प्रयास करते समय हमारा एप्लिकेशन विफल हो रहा था। अपवाद इस तरह दिखते थे:
त्रुटि सिस्टम। अमान्यऑपरेशन अपवाद:मध्यांतर बीत गया। पूल से कनेक्शन प्राप्त करने से पहले समयबाह्य अवधि समाप्त हो गई। ऐसा इसलिए हो सकता है क्योंकि सभी पूल किए गए कनेक्शन उपयोग में थे और अधिकतम पूल आकार तक पहुंच गया था।
कनेक्शन पूल
याद रखें कि .Net प्रत्येक क्वेरी पर कनेक्शन स्थापित करने के ऊपरी हिस्से से बचने में मदद के लिए कनेक्शन पूल का उपयोग करता है। प्रत्येक कनेक्शन स्ट्रिंग के लिए कनेक्शन पूल बनाए रखा जाता है और डिफ़ॉल्ट रूप से पूल में कनेक्शन की संख्या सौ पर कैप की जाती है। एक सौ कनेक्शन आमतौर पर पर्याप्त होते हैं। हमें इस अपवाद से पहले कभी कोई समस्या नहीं हुई और हमारे सर्वर सामान्य से अधिक व्यस्त नहीं थे इसलिए हम MaxPoolSize के मूल्य को बढ़ाने में संकोच कर रहे थे। हमें डेटाबेस कनेक्शन लीक होने का संदेह होने लगा।
डेटाबेस कनेक्शन लीक
मेमोरी लीक की तरह, डेटाबेस कनेक्शन लीक हो सकता है यदि आप समय पर अपने डेटाबेस कनेक्शन का निपटान नहीं करते हैं। SqlConnections IDisposable हैं इसलिए उपयोग कथन का उपयोग करना सबसे अच्छा अभ्यास है:
using (SqlConnection conn = new SqlConnection(connectionString)) { conn.Open(); // etc... }
जैसे ही आप SqlConnection के साथ काम करते हैं, इसका निपटारा हो जाता है और वास्तविक कनेक्शन तुरंत कनेक्शन पूल में वापस आ जाता है ताकि इसे किसी और द्वारा उपयोग किया जा सके। अन्यथा कनेक्शन तब तक उपयोग में रहता है जब तक कि प्रक्रिया समाप्त नहीं हो जाती या कचरा संग्रह इसे साफ नहीं कर देता।
अपने कनेक्शन के लीक होने का पता लगाना
इसलिए, यदि आपका एप्लिकेशन डेटाबेस कनेक्शन रिसाव के कारण कनेक्शन टाइमआउट का अनुभव करता है, तो स्टैक ट्रेस आपकी मदद नहीं कर सकते हैं। मेमोरी लीक के कारण आउट-ऑफ-मेमोरी अपवाद की तरह ही स्टैक ट्रेस में पीड़ित के बारे में जानकारी होती है, लेकिन मूल कारण नहीं। तो आप रिसाव का पता लगाने के लिए कहां जा सकते हैं?
भले ही डेटाबेस कनेक्शन लीक एक क्लाइंट समस्या है, आप डेटाबेस सर्वर से सहायता प्राप्त कर सकते हैं। डेटाबेस सर्वर पर, प्रत्येक पूल के आकार का अनुमानित अनुमान प्राप्त करने के लिए प्रति डेटाबेस प्रति प्रक्रिया कनेक्शन देखें:
select count(*) as sessions, s.host_name, s.host_process_id, s.program_name, db_name(s.database_id) as database_name from sys.dm_exec_sessions s where is_user_process = 1 group by host_name, host_process_id, program_name, database_id order by count(*) desc;
प्रोग्राम का नाम, होस्ट नाम, प्रक्रिया आईडी और डेटाबेस नाम आमतौर पर समान कनेक्शन पूल से आने वाले कनेक्शन की पहचान करने के लिए पर्याप्त होते हैं।
यह मुझे कई कनेक्शन वाले पूल के बारे में कुछ और प्रश्न पूछने के लिए प्रेरित करता है। एक पूल को देखते हुए, क्या ऐसे सत्र हैं जो कुछ समय से सो रहे हैं और यदि हां, तो वे कितने समय से सो रहे हैं और अंतिम SQL कथन क्या निष्पादित किया गया था?
declare @host_process_id int = 1508; declare @host_name sysname = N'SERV4102'; declare @database_name sysname = N'My_Database'; select datediff(minute, s.last_request_end_time, getdate()) as minutes_asleep, s.session_id, db_name(s.database_id) as database_name, s.host_name, s.host_process_id, t.text as last_sql, s.program_name from sys.dm_exec_connections c join sys.dm_exec_sessions s on c.session_id = s.session_id cross apply sys.dm_exec_sql_text(c.most_recent_sql_handle) t where s.is_user_process = 1 and s.status = 'sleeping' and db_name(s.database_id) = @database_name and s.host_process_id = @host_process_id and s.host_name = @host_name and datediff(second, s.last_request_end_time, getdate()) > 60 order by s.last_request_end_time;
टेक्स्ट का उपयोग अब आपके एप्लिकेशन के कोड बेस को खोजने के लिए किया जा सकता है ताकि यह पता लगाया जा सके कि आपके पास डेटाबेस कनेक्शन लीक कहां हो सकता है।
ये प्रश्न डेटाबेस कनेक्शन रिसाव के निवारण के लिए उपयोगी होते हैं और इनका उपयोग मॉनिटर या स्वास्थ्य जांच बनाने के लिए भी किया जा सकता है।
अपने डिस्पोज़ेबल का निपटान करें, उन उपयोगों का उपयोग करें, उन लीक को सील करें!