2012-01-25 19 views
15

मैं डरावना देख रहा हूं "पूल से कनेक्शन प्राप्त करने से पहले टाइमआउट अवधि समाप्त हो गई" त्रुटि।लीकिंग डीबी कनेक्शन पूल हैंडल कैसे ढूंढें?

मैंने किसी भी संलग्न डीबी कनेक्शन के लिए कोड खोजा है, लेकिन कोई भी नहीं मिला।

मैं जो करना चाहता हूं वह यह है: अगली बार जब हमें यह त्रुटि मिलती है, तो सिस्टम को सभी हैंडल धारण करने वाले प्रोसेस या http अनुरोधों की एक सूची डंप करें, इसलिए मैं समझ सकता हूं कि कौन सा कोड समस्या पैदा कर रहा है।

यह देखने के लिए भी बेहतर होगा कि उन हैंडल कितने समय तक आयोजित किए गए थे, इसलिए मैं प्रयुक्त-लेकिन-संलग्न कनेक्शनों को खोज सकता था।

क्या ऐसा करने का कोई तरीका है?

+0

क्या यह संभव है आप पूल में कनेक्शन से अधिक उपयोगकर्ता हो? –

+0

क्या आप सत्र स्थिति में कहीं और अपने जीवन संदर्भ को संग्रहीत करते हैं जिसमें जीवन भर है जो एक http अनुरोध से अधिक है? – Jan

+0

नहीं, वे अभी खोले गए हैं और (माना जाता है) प्रत्येक अनुरोध पर बंद कर दिया गया है। – Jesse

उत्तर

5

निगरानी कनेक्शन पूल के लिए कुछ अच्छे लिंक हैं न। ".net कनेक्शन पूल निगरानी" के लिए एक Google खोज करें।

एक लेख जिसे मैं थोड़ी देर पहले संदर्भित करता था Bill Vaughn's article था (नोट यह पुराना है लेकिन अभी भी उपयोगी जानकारी है)। इसमें कनेक्शन पूल की निगरानी करने के बारे में कुछ जानकारी है, लेकिन कुछ महान अंतर्दृष्टि जहां लीक भी हो सकती है।

निगरानी के लिए, वह सुझाव देता है;

"कनेक्शन पूल निगरानी

ठीक है, तो आप एक कनेक्शन खोला और इसे बंद कर दिया है और यदि कनेक्शन एक हवा गद्दे पर कनेक्शन पूल में जगह-सड़ में अब भी है जानना चाहते हैं। ठीक है ।, यह तय करने के कितने कनेक्शन अभी भी जगह (अभी भी जुड़े) और यहां तक ​​कि वे क्या कर रहे हैं में हैं कई तरीके हैं मैं पर चर्चा इन यहां के कई और मेरी किताब में:

· SQLProfiler साथ एसक्यूएल प्रोफाइलर का प्रयोग करें TSQL_Replayट्रेस के लिएटेम्पलेट। आप में से उन लोगों के लिए प्रोफाइलर से परिचित, SP_WHO का उपयोग करके मतदान से यह आसान है।

· भागो sp_who या SP_WHO2 है, जो प्रत्येक प्रक्रिया की वर्तमान स्थिति दिखा सभी कार्य प्रक्रियाओं पर sysprocesses तालिका से जानकारी लौटने। आम तौर पर, कनेक्शन प्रति एक एसपीआईडी ​​सर्वर प्रक्रिया है। यदि आपने कनेक्शन स्ट्रिंग में एप्लिकेशन नाम तर्क का उपयोग करके अपना कनेक्शन नाम दिया है, तो यह ढूंढना आसान होगा।

· पूल और कनेक्शन की निगरानी के लिए प्रदर्शन मॉनीटर (PerfMon) का उपयोग करें। मैं इसके बारे में विस्तार से चर्चा करता हूं।

· कोड में प्रदर्शन काउंटर मॉनीटर करें। यह विकल्प पर आपको अपने कनेक्शन पूल और स्थापित कनेक्शन की संख्या को प्रदर्शित करने या बस निगरानी करने की अनुमति देता है। मैं इस पेपर में के बाद के खंड में इस पर चर्चा करता हूं।"

संपादित करें:

हमेशा की तरह, बाहर other similar posts यहाँ से कुछ की जांच एसओ

दूसरा संपादित करें पर:

पुष्टि करने के बाद कि कनेक्शन नहीं हैं पूल द्वारा पुनः दावा किया जा रहा है, एक और चीज जिसे आप कोशिश कर सकते हैं, स्टेट चेंज इवेंट का उपयोग यह सुनिश्चित करने के लिए है कि कनेक्शन कब खोले जा रहे हैं और बंद हो जाएं। अगर आपको लगता है कि बहुत सारे मोर हैं ई बंद होने से खोले जाने के लिए राज्य परिवर्तन, तो इससे संकेत मिलेगा कि कहीं लीक हैं। इसके बाद आप टाइमएम्पैम्प के साथ स्टेटवर्क्स किए गए ईवेंट में डेटा लॉग भी कर सकते हैं, और यदि आपके पास अपने आवेदन पर कोई अन्य लॉगिंग है, तो आप लॉग फाइलों को उन उदाहरणों के लिए पार्स करना शुरू कर सकते हैं जहां खुले बंद होने के राज्य परिवर्तन होते हैं, साथ बंद करने के लिए कोई खुला खुला नहीं है। StateChangedEvent को संभालने के तरीके के बारे में अधिक जानकारी के लिए this link देखें।

+0

यदि कनेक्शन पूल में खुले रहते हैं, तो आप अनाथ होने पर एसक्यूएल प्रोफाइलर में कैसे देख सकते हैं? ऐसा लगता है कि मैं जो जानकारी चाहता हूं वह डीबी में नहीं है, लेकिन पूल-प्रबंधन परत में है। – Jesse

+0

मैं एसक्यूएल प्रोफाइलर विकल्प पर टिप्पणी नहीं कर सकता क्योंकि मैंने कनेक्शन पूल की निगरानी के लिए इसका उपयोग नहीं किया है। पेर्फमॉन और प्रदर्शन काउंटर से प्राप्त जानकारी के बारे में और जानकारी (आखिरी जोड़ी वह जिस बारे में बात करती है उसे पर मिल सकती है। इन ** केवल ** के बाद ** आपको "डरावनी त्रुटि" प्राप्त नहीं होगी ** ** ** जब उन्हें अनाथ बना दिया गया है। मैंने प्रदर्शन काउंटर का उपयोग करके डेटा को चुना है ताकि मुख्य रूप से कनेक्शन की संख्या की पुष्टि हो सके उपयोग किए जाने के बिना बढ़ता जा रहा है। एक बार पुष्टि हो जाने के बाद, आपको इसे शिकार करना होगा। –

+0

हम्म। बिल्कुल चांदी की बुलेट मैं नहीं ढूंढ रहा था, लेकिन मैं पूरी तरह से स्पष्टीकरण की सराहना करता हूं! – Jesse

0

मैं इस

http://www.simple-talk.com/sql/performance/how-to-identify-slow-running-queries-with-sql-profiler/

लंबे खोजने के लिए इससे पहले कि संग्रहित प्रक्रियाओं चल रहा है, मैं फिर वापस काम करते हैं और विधि है कि सपा बुलाया पा सकते हैं का उपयोग किया है।

पता है कि अगर मदद करेंगे

+0

समस्या (मुझे लगता है) मैं धीमे चलने वाले प्रश्नों के साथ नहीं हूं - यह कोड के साथ है जो एक क्वेरी चलाता है, फिर डीबी हैंडल को जाने नहीं देता है। – Jesse

13

यदि आप भाग्यशाली हैं कि कनेक्शन निर्माण/उद्घाटन केंद्रीकृत है तो निम्न वर्ग को लीक कनेक्शन को स्थानांतरित करना आसान बनाना चाहिए। आनंद लें :)

/// <summary> 
/// This class can help identify db connection leaks (connections that are not closed after use). 
/// Usage: 
/// connection = new SqlConnection(..); 
/// connection.Open() 
/// #if DEBUG 
/// new ConnectionLeakWatcher(connection); 
/// #endif 
/// That's it. Don't store a reference to the watcher. It will make itself available for garbage collection 
/// once it has fulfilled its purpose. Watch the visual studio debug output for details on potentially leaked connections. 
/// Note that a connection could possibly just be taking its time and may eventually be closed properly despite being flagged by this class. 
/// So take the output with a pinch of salt. 
/// </summary> 
public class ConnectionLeakWatcher : IDisposable 
{ 
    private readonly Timer _timer = null; 

    //Store reference to connection so we can unsubscribe from state change events 
    private SqlConnection _connection = null; 

    private static int _idCounter = 0; 
    private readonly int _connectionId = ++_idCounter; 

    public ConnectionLeakWatcher(SqlConnection connection) 
    { 
     _connection = connection; 
     StackTrace = Environment.StackTrace; 

     connection.StateChange += ConnectionOnStateChange; 
     System.Diagnostics.Debug.WriteLine("Connection opened " + _connectionId); 

     _timer = new Timer(x => 
     { 
      //The timeout expired without the connection being closed. Write to debug output the stack trace of the connection creation to assist in pinpointing the problem 
      System.Diagnostics.Debug.WriteLine("Suspected connection leak with origin: {0}{1}{0}Connection id: {2}", Environment.NewLine, StackTrace, _connectionId); 
      //That's it - we're done. Clean up by calling Dispose. 
      Dispose(); 
     }, null, 10000, Timeout.Infinite); 
    } 

    private void ConnectionOnStateChange(object sender, StateChangeEventArgs stateChangeEventArgs) 
    { 
     //Connection state changed. Was it closed? 
     if (stateChangeEventArgs.CurrentState == ConnectionState.Closed) 
     { 
      //The connection was closed within the timeout 
      System.Diagnostics.Debug.WriteLine("Connection closed " + _connectionId); 
      //That's it - we're done. Clean up by calling Dispose. 
      Dispose(); 
     } 
    } 

    public string StackTrace { get; set; } 

    #region Dispose 
    private bool _isDisposed = false; 

    public void Dispose() 
    { 
     if (_isDisposed) return; 

     _timer.Dispose(); 

     if (_connection != null) 
     { 
      _connection.StateChange -= ConnectionOnStateChange; 
      _connection = null; 
     } 

     _isDisposed = true; 
    } 

    ~ConnectionLeakWatcher() 
    { 
     Dispose(); 
    } 
    #endregion 
} 
+0

इससे हमें एक कनेक्शन खोला गया और कभी बंद नहीं हुआ वास्तव में शांत वर्ग :) बहुत बहुत धन्यवाद! – Challe

+0

अद्भुत! यह जानकर खुशी हुई कि यह दूसरों के लिए उपयोग किया जा सकता है। – LOAS

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