अपने पिछले लेख में मैंने कुंडी पर एक नई श्रृंखला शुरू की थी, यह समझाकर कि वे क्या हैं, उनकी आवश्यकता क्यों है, और वे कैसे काम करते हैं, और मैं दृढ़ता से अनुशंसा करता हूं कि आप इस लेख से पहले उस लेख को पढ़ लें। इस लेख में मैं FGCB_ADD_REMOVE कुंडी पर चर्चा करने जा रहा हूं और दिखाऊंगा कि यह कैसे एक अड़चन हो सकती है।
FGCB_ADD_REMOVE कुंडी क्या है?
अधिकांश कुंडी वर्ग के नाम सीधे डेटा संरचना से जुड़े होते हैं जिनकी वे रक्षा करते हैं। FGCB_ADD_REMOVE लैच FGCB, या फ़ाइल ग्रुप कंट्रोल ब्लॉक नामक डेटा संरचना की सुरक्षा करता है, और SQL सर्वर इंस्टेंस में प्रत्येक ऑनलाइन डेटाबेस के प्रत्येक ऑनलाइन फ़ाइलग्रुप के लिए इनमें से एक लैच होगा। जब भी किसी फ़ाइलग्रुप में कोई फ़ाइल जोड़ी जाती है, गिराई जाती है, विकसित की जाती है, या सिकुड़ती है, तो लैच को EX मोड में अधिग्रहित किया जाना चाहिए, और अगली फ़ाइल को आवंटित करने के लिए, किसी भी फ़ाइलग्रुप परिवर्तन को रोकने के लिए लैच को SH मोड में अधिग्रहित किया जाना चाहिए। (याद रखें कि फ़ाइल समूह के लिए सीमा आवंटन फ़ाइल समूह में फ़ाइलों के माध्यम से राउंड-रॉबिन आधार पर किया जाता है, और आनुपातिक भरण को भी ध्यान में रखा जाता है। , जो मैं यहाँ समझाता हूँ।)
कुंडी कैसे एक अड़चन बन जाती है?
सबसे आम परिदृश्य जब यह कुंडी एक अड़चन बन जाती है, तो वह इस प्रकार है:
- एक एकल फ़ाइल डेटाबेस है, इसलिए सभी आवंटन उसी एक डेटा फ़ाइल से आना चाहिए
- फ़ाइल के लिए ऑटोग्रो सेटिंग बहुत छोटी है (याद रखें, SQL सर्वर 2016 से पहले, डेटा फ़ाइलों के लिए डिफ़ॉल्ट ऑटोग्रो सेटिंग 1MB थी!)
- कई समवर्ती संचालन हैं जिन्हें आवंटित करने के लिए स्थान की आवश्यकता होती है (उदाहरण के लिए कई क्लाइंट कनेक्शन से लगातार सम्मिलित कार्यभार)
इस मामले में, भले ही केवल एक फ़ाइल है, फिर भी आवंटन की आवश्यकता वाले थ्रेड को SH मोड में FGCB_ADD_REMOVE लैच प्राप्त करना होगा। यह तब एकल डेटा फ़ाइल से आवंटित करने का प्रयास करेगा, यह महसूस करेगा कि कोई स्थान नहीं है, और फिर EX मोड में लैच प्राप्त करें ताकि यह फ़ाइल को बढ़ा सके।
आइए कल्पना करें कि आठ अलग-अलग शेड्यूलर पर चलने वाले आठ थ्रेड सभी एक ही समय में आवंटित करने का प्रयास करते हैं, और सभी को एहसास होता है कि फ़ाइल में कोई स्थान नहीं है, इसलिए उन्हें इसे विकसित करने की आवश्यकता है। वे प्रत्येक EX मोड में कुंडी प्राप्त करने का प्रयास करेंगे। उनमें से केवल एक ही इसे प्राप्त करने में सक्षम होगा और यह फ़ाइल को विकसित करने के लिए आगे बढ़ेगा और अन्य को प्रतीक्षा करनी होगी, प्रतीक्षा प्रकार LATCH_EX और FGCB_ADD_REMOVE के संसाधन विवरण के साथ-साथ कुंडी का स्मृति पता।
सात प्रतीक्षा धागे कुंडी की पहली-इन-फर्स्ट-आउट (फीफो) प्रतीक्षा कतार में हैं। जब फ़ाइल विकास करने वाला थ्रेड किया जाता है, तो यह कुंडी को छोड़ता है और इसे पहले प्रतीक्षा थ्रेड को अनुदान देता है। कुंडी का यह नया मालिक फ़ाइल को विकसित करने के लिए जाता है और पता चलता है कि यह पहले से ही बड़ा हो चुका है और कुछ भी नहीं करना है। तो यह कुंडी को छोड़ता है और अगले प्रतीक्षा धागे को देता है। और इसी तरह।
सात प्रतीक्षा धागे सभी EX मोड में कुंडी के लिए इंतजार कर रहे थे, लेकिन एक बार कुंडी दिए जाने के बाद कुछ भी नहीं कर रहे थे, इसलिए सभी सात धागे अनिवार्य रूप से बीता हुआ समय बर्बाद कर रहे थे, प्रत्येक धागे के लिए समय की मात्रा थोड़ी बढ़ रही थी और आगे नीचे FIFO प्रतीक्षा कतार थी।
अड़चन दिखा रहा है
अब मैं आपको विस्तारित घटनाओं का उपयोग करके उपरोक्त सटीक परिदृश्य दिखाने जा रहा हूं। मैंने एक छोटी ऑटोग्रो सेटिंग के साथ सिंगल-फाइल डेटाबेस बनाया है, और सैकड़ों समवर्ती कनेक्शन केवल एक टेबल में डेटा डालने के साथ।
क्या हो रहा है यह देखने के लिए मैं निम्नलिखित विस्तारित ईवेंट सत्र का उपयोग कर सकता हूं:
-- Drop the session if it exists. IF EXISTS ( SELECT * FROM sys.server_event_sessions WHERE [name] = N'FGCB_ADDREMOVE' ) BEGIN DROP EVENT SESSION [FGCB_ADDREMOVE] ON SERVER; END GO CREATE EVENT SESSION [FGCB_ADDREMOVE] ON SERVER ADD EVENT [sqlserver].[database_file_size_change] (WHERE [file_type] = 0), -- data files only ADD EVENT [sqlserver].[latch_suspend_begin] (WHERE [class] = 48 AND [mode] = 4), -- EX mode ADD EVENT [sqlserver].[latch_suspend_end] (WHERE [class] = 48 AND [mode] = 4) -- EX mode ADD TARGET [package0].[ring_buffer] WITH (TRACK_CAUSALITY = ON); GO -- Start the event session ALTER EVENT SESSION [FGCB_ADDREMOVE] ON SERVER STATE = START; GO
सत्र ट्रैक कर रहा है जब कोई थ्रेड कुंडी की प्रतीक्षा कतार में प्रवेश करता है, जब वह कतार छोड़ता है (अर्थात जब उसे कुंडी दी जाती है), और जब कोई डेटा फ़ाइल वृद्धि होती है। कार्य-कारण ट्रैकिंग का उपयोग करने का अर्थ है कि हम प्रत्येक थ्रेड द्वारा क्रियाओं की एक समयरेखा देख सकते हैं।
SQL सर्वर प्रबंधन स्टूडियो का उपयोग करके, मैं विस्तारित ईवेंट सत्र के लिए लाइव डेटा देखें विकल्प का चयन कर सकता हूं और सभी विस्तारित ईवेंट गतिविधि देख सकता हूं। यदि आप ऐसा करना चाहते हैं, तो लाइव डेटा विंडो में, शीर्ष पर कॉलम नामों में से किसी एक पर राइट क्लिक करें और चयनित कॉलम को नीचे की तरह बदलें:
मैंने कार्यभार को स्थिर स्थिति तक पहुंचने के लिए कुछ मिनटों तक चलने दिया और फिर मैंने ऊपर वर्णित परिदृश्य का एक आदर्श उदाहरण देखा:
attach_activity_id.guid . का उपयोग करना विभिन्न धागों की पहचान करने के लिए, हम देख सकते हैं कि सात धागे 61.5 माइक्रोसेकंड के भीतर कुंडी की प्रतीक्षा करना शुरू कर देते हैं। 8D57 से शुरू होने वाले GUID मान वाला थ्रेड EX मोड में लैच प्राप्त करता है (latch_suspend_end घटना) और फिर फ़ाइल को तुरंत बढ़ाता है (database_file_size_change प्रतिस्पर्धा)। 8D57 थ्रेड फिर कुंडी को छोड़ता है और इसे EX मोड में 6F82 थ्रेड में अनुदान देता है, जो 85 मिलीसेकंड तक प्रतीक्षा करता है। इसका कोई लेना-देना नहीं है इसलिए यह 672B धागे को कुंडी देता है। और इसी तरह, 202 मिलीसेकंड प्रतीक्षा करने के बाद, जब तक EDB8 थ्रेड को कुंडी नहीं दी जाती है।
कुल मिलाकर, बिना किसी कारण के प्रतीक्षा करने वाले छह सूत्र लगभग 1 सेकंड तक प्रतीक्षा करते रहे। उस समय में से कुछ सिग्नल प्रतीक्षा समय है, जहां भले ही थ्रेड को कुंडी दी गई हो, फिर भी इसे प्रोसेसर पर आने और कोड निष्पादित करने से पहले शेड्यूलर की चलने योग्य कतार के शीर्ष पर जाने की आवश्यकता होती है। आप कह सकते हैं कि यह कुंडी के इंतजार में बिताए गए समय का उचित माप नहीं है, लेकिन यह बिल्कुल है, क्योंकि अगर थ्रेड को पहले स्थान पर इंतजार नहीं करना पड़ता तो सिग्नल प्रतीक्षा समय खर्च नहीं होता।पी>
इसके अलावा, आप सोच सकते हैं कि 200 मिलीसेकंड की देरी इतनी अधिक नहीं है, लेकिन यह सब कार्यभार के लिए प्रदर्शन सेवा-स्तरीय समझौतों पर निर्भर करता है। हमारे पास कई उच्च-मात्रा वाले ग्राहक हैं, जहां यदि किसी बैच को निष्पादित होने में 200 मिलीसेकंड से अधिक समय लगता है, तो उत्पादन प्रणाली पर इसकी अनुमति नहीं है!
सारांश
यदि आप अपने सर्वर पर प्रतीक्षा की निगरानी कर रहे हैं और आप देखते हैं कि LATCH_EX शीर्ष प्रतीक्षा में से एक है, तो आप इस पोस्ट में कोड का उपयोग कर सकते हैं ताकि देखें कि FGCB_ADD_REMOVE अपराधियों में से एक है या नहीं।
यह सुनिश्चित करने का सबसे आसान तरीका है कि आपका कार्यभार FGCB_ADD_REMOVE अड़चन से नहीं टकरा रहा है, यह सुनिश्चित करना है कि कोई डेटा फ़ाइल ऑटोग्रो सेटिंग्स नहीं हैं जो पूर्व-SQL सर्वर 2016 डिफ़ॉल्ट का उपयोग करके कॉन्फ़िगर की गई हैं। sys.master_files . में देखें, तो 1MB डिफ़ॉल्ट डेटा फ़ाइल के रूप में दिखाई देगा (type_desc कॉलम को ROWS पर सेट किया गया है) is_percent_growth . के साथ कॉलम 0 पर सेट है, और ग्रोथ कॉलम 128 पर सेट है।
ऑटोग्रो को किस पर सेट किया जाना चाहिए, इसके लिए एक सिफारिश देना एक पूरी अन्य चर्चा है, लेकिन अब आप पिछले संस्करणों में डिफ़ॉल्ट को नहीं बदलने से संभावित प्रदर्शन प्रभाव के बारे में जानते हैं।