कुंडी पर लेखों की मेरी छोटी श्रृंखला को समाप्त करने के लिए, इस बार मैं SQL सर्वर में कुछ अन्य कुंडी पर चर्चा करने जा रहा हूँ जो आप कभी-कभार देख सकते हैं लेकिन अपने आप में एक पूर्ण लेख की योग्यता नहीं रखते हैं। हमेशा की तरह, मैं दृढ़ता से अनुशंसा करता हूं कि आप इससे पहले श्रृंखला में प्रारंभिक पोस्ट पढ़ लें, ताकि आपको कुंडी के बारे में सभी सामान्य पृष्ठभूमि का ज्ञान हो।
LOG_MANAGER कुंडी
लेन-देन लॉग से जुड़े कुछ कार्यों के दौरान सिंक्रनाइज़ेशन के लिए LOG_MANAGER लैच का उपयोग किया जाता है, और प्रति डेटाबेस एक LOG_MANAGER लैच होता है (क्योंकि प्रत्येक डेटाबेस का अपना लॉग मैनेजर होता है)। इसे केवल अनन्य मोड में प्राप्त किया जा सकता है और लेन-देन लॉग फ़ाइल वृद्धि के दौरान एक बाधा हो सकती है। वह परिदृश्य जहां यह एक समस्या के रूप में स्पष्ट हो जाएगा:
- लॉग फ़ाइल में एक छोटा ऑटोग्रोथ सेट होता है
- लेन-देन लॉग रिकॉर्ड बनाने वाले कई समवर्ती कनेक्शन हैं
- लॉग फ़ाइल बढ़ती रहती है
जब लॉग फ़ाइल स्थान से बाहर हो जाती है, तो उसे बढ़ने की आवश्यकता होगी। अधिक लॉग स्थान प्राप्त करने के लिए पहले थ्रेड की आवश्यकता होती है, EX मोड में LOG_MANAGER लैच प्राप्त करता है और लॉग फ़ाइल को विकसित करने के लिए आगे बढ़ता है। कई अन्य थ्रेड लॉग रिकॉर्ड बनाने और LOG_MANAGER लैच के लिए कतार में आने का प्रयास करना जारी रखते हैं, ताकि वे लॉग फ़ाइल को बढ़ा सकें। जब पहला धागा कुंडी छोड़ता है, तो अगला धागा इसे प्राप्त करता है और महसूस करता है कि लॉग पहले से ही बड़ा हो गया है, इसलिए इसे छोड़ देता है और जारी रहता है। और आगे और आगे। संयोग से, अड़चन के इस पैटर्न को कुंडी काफिला . कहा जाता है ।
आप इसे ठीक उसी तरह की अड़चन के रूप में सोच सकते हैं जैसे FGCB_ADD_REMOVE कुंडी के साथ मैंने पहले श्रृंखला में चर्चा की थी, लेकिन डेटा फ़ाइल वृद्धि के बजाय लॉग फ़ाइल वृद्धि के साथ। हालाँकि, FGCB_ADD_REMOVE लैच के साथ, आमतौर पर इंस्टेंस में इंस्टेंट फ़ाइल इनिशियलाइज़ेशन सक्षम होता है, इसलिए फ़ाइल का विकास बहुत तेज़ होता है, लेकिन LOG_MANAGER लैच के साथ, लॉग * जीरो-इनिशियलाइज़्ड होना चाहिए, और लैच कतार में बर्बाद होने वाला समय लंबा होता है। .
इस अड़चन के समाधान के तीन भाग हैं:
- लॉग फ़ाइल ऑटोग्रोथ को सही तरीके से सेट करें, ताकि लॉग बार-बार न बढ़े
- कार्यभार के लिए लॉग को सही आकार दें, ताकि लॉग बिल्कुल न बढ़े
- सुनिश्चित करें कि लॉग सही ढंग से साफ़ हो रहा है, इसलिए लॉग को बढ़ने की आवश्यकता नहीं है
यदि ये सब जगह पर हैं, तो आपको LOG_MANAGER कुंडी को एक नियमित अड़चन नहीं देखना चाहिए, और मैं यहाँ अपनी पोस्ट में इसके बारे में अधिक बात करता हूँ।
ACCESS_METHODS_DATASET_PARENT कुंडी
जब या तो एक हीप या इंडेक्स एक्सेस किया जा रहा होता है, तो आंतरिक रूप से एक ऑब्जेक्ट होता है जिसे क्रमशः HeapDataSetSession या IndexDataSetSession कहा जाता है। जब एक समानांतर स्कैन किया जा रहा होता है, तो स्कैन का वास्तविक कार्य करने वाले प्रत्येक थ्रेड में एक "चाइल्ड" डेटासेट होता है (दो वस्तुओं का एक और उदाहरण जो मैंने अभी वर्णित किया है), और मुख्य डेटासेट, जो वास्तव में स्कैन को नियंत्रित कर रहा है, कहा जाता है "माता-पिता।"
जब स्कैन वर्कर थ्रेड्स में से किसी एक ने उन पंक्तियों के सेट को समाप्त कर दिया है जिन्हें स्कैन करना है, तो उसे मूल डेटासेट तक पहुंचकर एक नई श्रेणी प्राप्त करने की आवश्यकता होती है, जिसका अर्थ है ACCESS_METHODS_DATASET_PARENT विशेष मोड में लैच प्राप्त करना। हालांकि यह एक अड़चन की तरह लग सकता है, यह वास्तव में नहीं है, और समानांतर स्कैन करने वाले थ्रेड्स को कभी-कभी इस कुंडी के लिए LATCH_EX प्रतीक्षा दिखाने से रोकने के लिए आप कुछ भी नहीं कर सकते हैं।
आपको अपने आप से जो प्रश्न पूछना चाहिए वह यह है:क्या यह प्रश्न पहली बार में समानांतर स्कैन कर रहा होगा? यह पूरी तरह से संभव है कि क्वेरी योजना को समानांतर स्कैन शामिल करने के लिए मजबूर करने के लिए कुछ हुआ हो, जब क्वेरी चलाने के लिए यह सबसे प्रभावी तरीका नहीं हो सकता है। उन चीज़ों के उदाहरण जो किसी योजना को समानांतर स्कैन में बदलने का कारण बन सकते हैं, उनमें शामिल हैं:
- पुराने आंकड़े
- एक गुम या गिरा हुआ गैर-संकुल सूचकांक
- एक अंतर्निहित रूपांतरण के कारण स्कैन को मजबूर करने वाला नया कोड-एक कॉलम और एक चर/पैरामीटर के बीच एक डेटा प्रकार बेमेल, जो एक गैर-संकुल सूचकांक के उपयोग को रोकता है
- नया कोड स्कैन के लिए बाध्य करता है क्योंकि अंकगणित एक चर/पैरामीटर के बजाय एक टेबल कॉलम पर किया जा रहा है, जो फिर से एक गैर-संकुल सूचकांक के उपयोग को रोकता है
- डेटा वृद्धि और एक स्कैन वास्तव में सबसे कुशल योजना है
या हो सकता है कि इस क्वेरी के लिए स्कैन की आवश्यकता हो, ऐसी स्थिति में LATCH_EX ACCESS_METHODS_DATASET_PARENT की प्रतीक्षा आपके परिवेश का ही हिस्सा है।
ACCESS_METHODS_HOBT_VIRTUAL_ROOT कुंडी
इस कुंडी का प्रत्येक उदाहरण बी-पेड़ के लिए स्टोरेज इंजन मेटाडेटा में एक प्रविष्टि की सुरक्षा करता है, विशेष रूप से बी-पेड़ के मूल पृष्ठ की पृष्ठ आईडी (त्रिकोण के शीर्ष पर पृष्ठ जिसे हम आम तौर पर एक इंडेक्स के रूप में सोचते हैं) . मैं विशेष रूप से कह रहा हूँ b-tree और नहीं अनुक्रमणिका , एक इंडेक्स के रूप में कई विभाजन हो सकते हैं, जिनमें से प्रत्येक में एक बी-ट्री होता है (अनिवार्य रूप से समग्र इंडेक्स का एक हिस्सा, लेकिन कम मूल्य और उच्च मूल्य कुंजी बाधाओं के साथ)।
हर बार एक थ्रेड को बी-ट्री को पार करने की आवश्यकता होती है, इसे रूट पेज से शुरू करना होता है और पत्ती के स्तर तक अपना काम करना होता है। रूट पेज के पेज आईडी वाले मेटाडेटा को पढ़ने के लिए, थ्रेड को SH मोड में ACCESS_METHODS_HOBT_VIRTUAL_ROOT लैच प्राप्त करना होगा, ताकि यह सुनिश्चित हो सके कि पेज आईडी बदलने की प्रक्रिया में नहीं है। जब किसी थ्रेड को रूट पेज की पेज आईडी बदलने की आवश्यकता होती है, तो उसे EX मोड में लैच प्राप्त करना होता है।
बी-पेड़ का मूल पृष्ठ कभी क्यों बदलेगा? जैसे-जैसे रूट पेज में इंडेक्स रिकॉर्ड्स की संख्या बढ़ती है, अंततः यह भर जाएगा और पेज स्प्लिट हो जाएगा। जब ऐसा होता है, तो वर्तमान रूट पेज और वह पेज जो विभाजित हो जाता है, बी-ट्री में एक नया स्तर बन जाता है, और एक नया रूट पेज बनाया जाता है, जिसमें दो इंडेक्स रिकॉर्ड होते हैं, जो पुराने रूट पेज और पेज को इंगित करते हैं। में विभाजित। नए रूट पेज आईडी को मेटाडेटा में दर्ज किया जाना है, इसलिए लैच EX मोड में प्राप्त किया जाता है। यह कुछ बार जल्दी होगा क्योंकि एक खाली टेबल पर एक इंडेक्स इंसर्ट से पॉप्युलेट होना शुरू हो जाता है, लेकिन ऐसा कुछ नहीं है जिसे आप चल रहे प्रदर्शन की समस्या के रूप में देखेंगे।
सारांश
जैसा कि मुझे यकीन है कि आप इस श्रृंखला से एकत्र हुए हैं, कुंडी और कुंडी बाधाओं को समझने में सामान्य प्रतीक्षा आंकड़ों के विश्लेषण की तुलना में स्टोरेज इंजन के अंदर क्या हो रहा है, इसके बारे में कुछ और जानना शामिल है।
मैं आमतौर पर लोगों को *नहीं* को लैच के आंकड़ों को देखकर (sys.dm_os_latch_stats के माध्यम से) प्रदर्शन समस्या निवारण शुरू करने की सलाह देता हूं ) लेकिन इसके बजाय हमेशा प्रतीक्षा आँकड़ों के साथ शुरू करें (मेरी पोस्ट यहाँ देखें) और केवल लैच में तल्लीन करें यदि LATCH_EX या LATCH_SH SQL सर्वर इंस्टेंस पर शीर्ष मुट्ठी भर प्रतीक्षा में से एक हैं।
यदि कुंडी के बारे में आपके कोई प्रश्न हैं, तो बेझिझक मुझे एक पंक्ति दें।