2009-06-13 11 views
9

मैं कुछ लॉगिंग/ऑडिटिंग कोड लिख रहा हूं जो उत्पादन में चल रहा है (न केवल जब त्रुटियों को फेंक दिया जाता है या विकास के दौरान)। Coding Horror's experiences with dead-locking and logging पढ़ने के बाद, मैंने फैसला किया कि मुझे सलाह लेनी चाहिए। (जेफ का "लॉगिंग नहीं" का समाधान मेरे लिए काम नहीं करेगा, यह कानूनी रूप से अनिवार्य सुरक्षा लेखा परीक्षा है)एमएस एसक्यूएल सर्वर में केवल एक तालिका में संलग्न करने पर लॉकिंग को कम करने के लिए सलाह?

क्या विवाद और मृत-लॉकिंग को कम करने के लिए उपयुक्त अलगाव स्तर है? कोई पूछताछ संकेत मैं सम्मिलित कथन या संग्रहीत प्रक्रिया में जोड़ सकते हैं?

मुझे ऑडिट तालिका को छोड़कर सबकुछ के लिए लेनदेन संबंधी अखंडता के बारे में गहराई से परवाह है। विचार यह है कि इतना लॉग इन किया जाएगा कि अगर कुछ प्रविष्टियां विफल हो जाती हैं, तो यह कोई समस्या नहीं है। अगर लॉगिंग कुछ अन्य लेनदेन बंद कर देता है - यह बुरा होगा।

मैं किसी डेटाबेस या फ़ाइल पर लॉग इन कर सकता हूं, हालांकि फ़ाइल में लॉग इन करना कम आकर्षक है क्योंकि मुझे किसी भी तरह के परिणाम प्रदर्शित करने में सक्षम होना चाहिए। किसी फ़ाइल में लॉग इन करना (लगभग) गारंटी देता है कि लॉगिंग अन्य कोड में हस्तक्षेप नहीं करेगी।

+0

एसक्यूएल सर्वर का कौन सा संस्करण? –

+0

एसक्यूएल 2000, हालांकि अफवाहें हैं कि किसी दिन कार्यालय एसक्यूएल 2008 पर कूद जाएगा। – MatthewMartin

उत्तर

5

एक सामान्य लेनदेन (यानी पढ़ें पढ़ा गया) डालने से पहले से ही 'न्यूनतम' लॉकिंग होता है। गहन अनुप्रयोग डालें, डालने पर डेडलॉक नहीं होगा, इससे कोई फर्क नहीं पड़ता कि अन्य परिचालनों के साथ सम्मिलन कैसे मिलाया जाता है। सबसे बुरी तरह से एक गहन डालने प्रणाली गर्म स्थान पर पेज लच विवाद का कारण बन सकती है जहां सम्मिलित होता है, लेकिन डेडलॉक्स नहीं।

  • प्रणाली एक उच्च अलगाव स्तर उपयोग कर रहा है (वे यह तो आने वाले थे और अच्छी तरह से इसके लायक:

    के रूप में निम्नलिखित में से किसी एक की तरह, जेफ से वहाँ है वर्णित खेल में अधिक होने की गतिरोध पैदा करने के लिए)

  • वे लॉग मेज से लेनदेन के दौरान पढ़ रहे थे (ताकि लंबे समय तक undetectable जिसका परिणाम नहीं 'संलग्न-केवल')
  • गतिरोध श्रृंखला शामिल अनुप्रयोग परत ताले (यानी। नेट log4net ढांचे में lock बयान) है deadlocks (यानी आवेदन लटका)। यह देखते हुए कि प्रक्रिया डंप को देखते हुए समस्या को हल करने के लिए, मुझे लगता है कि यह वह परिदृश्य है जो वे कर रहे थे।

तो जब तक आप केवल पढ़ने के लिए अलग-अलग अलगाव स्तर लेनदेन में लॉग इन करते हैं, तो आप सुरक्षित हैं। यदि आप एक ही समस्या की अपेक्षा करते हैं तो मुझे संदेह है कि एसओ (यानी डेडलॉक्स एप्लिकेशन लेयर लॉक शामिल हैं) तो डेटाबेस विज़ार्ड की कोई मात्रा आपको सहेज नहीं सकती है, क्योंकि समस्या तब भी प्रकट हो सकती है जब आप अलग लेनदेन पर लॉग इन करते हैं या अलग कनेक्शन में लॉग ऑन करते हैं।

+1

"तब तक जब तक आप केवल समेकित अलगाव स्तर लेनदेन में लॉग इन करते हैं तो आप सुरक्षित होते हैं।" यह सच नहीं है। यदि आप बड़े लेन-देन में भाग ले रहे हैं तो आप लॉजिंग टेबल को सम्मिलित करने का प्रयास करते समय पूरे लेनदेन को अवरुद्ध कर सकते हैं (यदि लॉगिंग तालिका अवरुद्ध है क्योंकि आप इसे कुछ पागल रिपोर्ट चला रहे हैं या कुछ)। इसके अलावा यह आपको केंद्रीय डेडलॉक तक खुलता है! –

+2

नहीं, बस सच नहीं है। INSERT * (पढ़ा गया) रिपोर्ट के पीछे ब्लॉक नहीं करेगा, इससे कोई फर्क नहीं पड़ता कि आप लेनदेन में क्या करते हैं। इसके अलावा समवर्ती इंसर्ट्स डेडलॉक चेन में कभी नहीं दिखाई देंगे, क्योंकि वे एक दूसरे के पीछे और न ही पीछे के पीछे ब्लॉक नहीं करते हैं। चीजें जो एक डालने को अवरुद्ध कर सकती हैं वे हैं: एक रेंज एस लॉक जो सम्मिलित बिंदु (यानी एक धारावाहिक रिपोर्ट) को कवर करता है, तालिका पर एक एस लॉक (यानी दोहराने योग्य रिपोर्ट से वृद्धि) या एक्स ताले (यानी कुछ गतिविधि * अन्य * केवल 'संलग्न करें' की तुलना में, जैसे कि एक्स एक्स लॉक में अपडेट किए गए अपडेट)। –

+2

पढ़ने में एक तालिका (क्लस्टर्ड इंडेक्स के साथ) में INSERT पृष्ठ पर एक आईएक्स लॉक प्राप्त करता है और कुंजी पर एक्स लॉक प्राप्त करता है। यदि यह पृष्ठ पर आईएक्स लॉक नहीं प्राप्त कर सकता है तो यह इंतजार करेगा, अगर यह अधिग्रहण नहीं कर सकता है और कुंजी पर एक्स लॉक होगा तो यह इंतजार करेगा। चयन कथन साझा ताले की जरूरत है। ताले संघर्ष कर सकते हैं। डेडलॉक्स मौजूद हो सकते हैं। पढ़ें: http://msdn.microsoft.com/en-us/library/ms186396.aspx –

1

चूंकि आपको ऑडिट तालिका की लेनदेन की अखंडता की परवाह नहीं है, इसलिए आप स्पष्ट रूप से लेनदेन के बाहर लॉगिंग कर सकते हैं (यानी इसे पूरा करने के बाद)। इससे लेनदेन पर असर कम हो जाएगा।

इसके अलावा, यदि आप लॉकिंग को कम करना चाहते हैं, तो आपको यह सुनिश्चित करने की कोशिश करनी चाहिए कि जितना संभव हो उतना आपके क्वेरी वर्कलोड में गैर-क्लस्टर इंडेक्स शामिल हैं। (एसक्यूएल सर्वर 2005 और ऊपर, एनसी इंडेक्स में INCLUDE कथन का उपयोग एक बड़ा अंतर कर सकता है)

+0

नोट: यदि आप लेनदेन पूरा होने के बाद सभी लॉगिंग करते हैं, तो यह लंबे समय तक चलने वाले लेनदेन या निरस्त लेनदेन को डीबग करना मुश्किल हो जाता है। –

+0

पोस्टर ने पहले ही यह स्पष्ट कर दिया है कि इससे कोई फर्क नहीं पड़ता कि लॉगिंग विफल हो जाती है, जब तक एक लेनदेन पूरा हो जाता है। जाहिर है, लेनदेन जितना संभव हो उतना छोटा होना चाहिए। –

+0

सभी आईएम कह रहे हैं कि इस संदर्भ में (यानी एक अलग थ्रेड में) संभवतया बेहतर है (यानी इसे पूरा करने के बाद) –

1

आपके लॉगिंग को आपके 'नियमित' डेटाबेस से लॉक करने से रोकने का एक आसान तरीका उसी डेटाबेस का उपयोग नहीं करना है । बस अपने लॉगिंग के लिए एक और डेटाबेस बनाएँ। बोनस के रूप में, आपके लॉगिंग डेटाबेस की तेज़ी से वृद्धि के परिणामस्वरूप आपके मुख्य डीबी में विखंडन नहीं होगा। व्यक्तिगत, मैं आमतौर पर एक फ़ाइल में लॉग करना पसंद करता हूं - लेकिन फिर, मैं अपने संपादक - वीआईएम में भारी टेक्स्ट मैनिपुलेशन करने के लिए उपयोग किया जाता हूं। एक अलग डीबी में लॉग इन करने से डेडलॉकिंग मुद्दों से बचने में मदद मिलनी चाहिए।

बस यह सुनिश्चित करें कि यदि आप लॉगिंग फ्रेमवर्क के लिए अपना खुद का डेटाबेस एपेंडर लिखने का प्रयास करते हैं, तो आप अपने ताले के बारे में बहुत सावधान रहें (जो मुझे लगता है कि ब्लॉग पोस्ट में जेफ को किस चीज में फिसल गया है)। उचित रूप से लिखा गया (जेफ की पोस्ट में कई टिप्पणियां देखें), आपको अपने लॉगिंग फ्रेमवर्क के साथ लॉकिंग समस्याएं नहीं होनी चाहिए जब तक कि वे अजीब कुछ नहीं करते।

+0

मुझे लगता है कि लॉगिंग टेबल के लिए सिर्फ एक नया डेटाबेस शुरू करना आक्रामक है, आप हमेशा स्टोरेज स्थान को नियंत्रित कर सकते हैं यदि आवश्यक हो तो फ़ाइल समूह का उपयोग करके प्रत्येक तालिका में। यह भी नहीं कि यदि आपने जगह पर लेनदेन वितरित किया है तो एक अलग डीबी पर लॉग इन करने से वास्तव में सामान खराब हो सकता है यदि वह ऑपरेशन वितरित लेनदेन में भाग ले रहा है। –

+0

यदि आप वितरित लेनदेन का उपयोग कर रहे हैं, तो मैं सलाह दूंगा कि * आपके * में लॉगिंग प्रविष्टि न हो। लेन-देन रोलबैक के कारण कुछ ब्रेक होने की तरह कुछ नहीं, और जो भी टूट गया है उसका कोई लॉग नहीं है ... –

5

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

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

लॉगिंग थ्रेड, chuck it on a queue में लॉकिंग थ्रेड में अपने सभी लॉगिंग डेटा को पकड़ें, जब नए लॉगिंग संदेश हों, तो उन्हें एक ही लेनदेन में डीबी में फ़्लश करें।

को न्यूनतम लॉक करने के चरण:

  • (प्रमुख) प्रदर्शन सभी मुख्य थ्रेड/कनेक्शन/लेन-देन के बाहर प्रवेश मेज पर जोड़ देता है।
  • सुनिश्चित करें कि आपकी लॉगिंग तालिका में एक monotonically बढ़ती क्लस्टर्ड इंडेक्स (जैसे int पहचान) है जो हर बार जब आप लॉग संदेश जोड़ते हैं तो बढ़ रहा है। यह सुनिश्चित करता है कि पृष्ठों को आमतौर पर स्मृति में डाला जा रहा है और हेप टेबल के साथ मिलने वाली प्रदर्शन हिट से बचाता है।
  • एक लेनदेन में लॉग में एकाधिक संलग्न करें (लेनदेन में 10 आवेषण लेनदेन से 10 आवेषण से अधिक तेज़ होते हैं और आम तौर पर कम ताले प्राप्त करते हैं/रिलीज़ होते हैं)
  • इसे ब्रेक दें। केवल अपने डीबी प्रत्येक एन मिलीसेकंड में लॉगिंग करें। कार्यों के बिट्स बैच करें।
  • यदि आपको ऐतिहासिक रूप से सामानों पर रिपोर्ट करने की आवश्यकता है, तो आप अपनी लॉगिंग तालिका को विभाजित करने पर विचार कर सकते हैं। उदाहरण: आप हर महीने एक नई लॉगिंग टेबल बना सकते हैं, और साथ ही एक लॉग दृश्य भी है जो यूनियन है सभी पुरानी लॉगिंग टेबलों में से सभी। सबसे उपयुक्त स्रोत के खिलाफ रिपोर्टिंग करें।

आप एक एकल (छोटा सा) लेन-देन में एक से अधिक प्रवेश संदेशों निस्तब्धता द्वारा बेहतर प्रदर्शन प्राप्त होगा, और लाभ 10 धागे काम करते हैं और लॉगिंग सामान कर रहे हैं, केवल एक ही धागे प्रवेश मेज पर सामान निस्तब्धता है कि है । यह पाइपलाइनिंग वास्तव में सामान पैमाने को बेहतर बनाती है।

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