SQL सर्वर इंडेक्स अपडेट डेडलॉक


13

मेरे पास 2 प्रश्न हैं जो एक ही समय में चलने पर गतिरोध पैदा कर रहे हैं।

क्वेरी 1 - एक कॉलम को अपडेट करें जो एक इंडेक्स (इंडेक्स 1) में शामिल है:

update table1 set column1 = value1 where id = @Id

X1 को X-Lock लेता है, फिर index1 पर X-Lock का प्रयास करता है।

क्वेरी 2:

select columnx, columny, etc from table1 where {some condition}

Index1 पर S-Lock लेता है, फिर table1 पर S-Lock का प्रयास करता है।

क्या समान प्रश्नों को बनाए रखते हुए गतिरोध को रोकने का कोई तरीका है? उदाहरण के लिए क्या मैं अपडेट लेन-देन में सूचकांक पर एक्स-लॉक को किसी तरह ले सकता हूं ताकि यह सुनिश्चित करने के लिए अपडेट से पहले कि टेबल और इंडेक्स एक्सेस एक ही क्रम में हों - जो गतिरोध को रोकना चाहिए?

अलगाव स्तर पढ़ें प्रतिबद्ध है। अनुक्रमणिका के लिए पंक्ति और पृष्ठ लॉक सक्षम होते हैं। यह संभव है कि एक ही रिकॉर्ड दोनों प्रश्नों में भाग ले रहा हो - मैं गतिरोध ग्राफ से नहीं बता सकता क्योंकि यह पैरामीटर नहीं दिखाता है।

गतिरोध ग्राफ

जवाबों:


11

क्या समान प्रश्नों को बनाए रखते हुए गतिरोध को रोकने का कोई तरीका है?

गतिरोध ग्राफ से पता चलता है कि यह विशेष गतिरोध एक बुकमार्क लुकअप (इस मामले में एक RID लुकअप) से जुड़ा रूपांतरण गतिरोध था:

गतिरोध ग्राफ

जैसा कि प्रश्न नोट करता है, सामान्य गतिरोध का जोखिम इसलिए उठता है क्योंकि प्रश्न विभिन्न क्रमों में समान संसाधनों पर असंगत ताले प्राप्त कर सकते हैं। SELECTक्वेरी, RID देखने की वजह से मेज से पहले सूचकांक का उपयोग करने की जरूरत है, जबकि UPDATEसूचकांक क्वेरी संशोधित तालिका पहले, तो।

गतिरोध को खत्म करने के लिए गतिरोध सामग्री में से एक को हटाने की आवश्यकता होती है। निम्नलिखित मुख्य विकल्प हैं:

  1. गैर-अनुक्रमित अनुक्रमणिका बनाकर RID लुकअप से बचें। यह संभवतः आपके मामले में व्यावहारिक नहीं है क्योंकि SELECTक्वेरी 26 कॉलम लौटाती है।
  2. क्लस्टर इंडेक्स बनाकर RID लुकअप से बचें। इसमें कॉलम पर एक क्लस्टर इंडेक्स बनाना शामिल होगा Proposal। यह विचार करने योग्य है, हालांकि यह प्रतीत होता है कि यह स्तंभ प्रकार का है uniqueidentifier, जो व्यापक मुद्दों पर निर्भर करते हुए क्लस्टर इंडेक्स के लिए एक अच्छा विकल्प हो सकता है या नहीं।
  3. READ_COMMITTED_SNAPSHOTया SNAPSHOTडेटाबेस विकल्पों को सक्षम करके पढ़ते समय साझा ताले लेने से बचें । इसके लिए सावधानीपूर्वक परीक्षण की आवश्यकता होगी, विशेष रूप से किसी भी डिज़ाइन-इन ब्लॉकिंग व्यवहार के संबंध में। ट्रिगर कोड को तर्क को सही ढंग से निष्पादित करने के लिए परीक्षण की भी आवश्यकता होगी।
  4. क्वेरी के READ UNCOMMITTEDलिए आइसोलेशन स्तर का उपयोग करते हुए साझा किए गए ताले लेने से बचें SELECT। सभी सामान्य कैविएट लागू होते हैं।
  5. एक विशेष एप्लिकेशन लॉक का उपयोग करके प्रश्न में दो प्रश्नों के समवर्ती निष्पादन से बचें (देखें sp_getapplock )।
  6. सुगमता से बचने के लिए टेबल लॉक संकेत का उपयोग करें। यह विकल्प 5 की तुलना में एक बड़ा हथौड़ा है, क्योंकि यह अन्य प्रश्नों को प्रभावित कर सकता है, न कि प्रश्न में पहचाने गए दो।

क्या मैं टेबल और इंडेक्स एक्सेस को एक ही क्रम में सुनिश्चित करने के लिए अपडेट से पहले अपडेट लेन-देन में सूचकांक पर एक्स-लॉक ले सकता हूं

आप एक स्पष्ट लेनदेन में अद्यतन को लपेटकर और अपडेट से पहले गैर-अनुक्रमित सूचकांक मूल्य पर SELECTएक XLOCKसंकेत के साथ यह कोशिश कर सकते हैं । यह आप पर निर्भर करता है कि यह जानने के लिए कि गैर-अनुक्रमित सूचकांक में वर्तमान मूल्य क्या है, निष्पादन योजना सही हो रही है, और इस अतिरिक्त लॉक को लेने के सभी दुष्प्रभावों का सही अनुमान लगा रही है। यह लॉकिंग इंजन पर भी निर्भर करता है कि स्मार्ट होने के कारण लॉक होने से बचने के लिए पर्याप्त स्मार्ट नहीं है बेमानी होने फैसला

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


इस मुद्दे पर आगे देखने से मुझे लगता है कि इसे अपरिवर्तित रखना शायद सबसे अच्छा है। यह एक अधिक सामान्य समस्या है जो मुझे मूल रूप से महसूस हुई।
डेल के

1

मेरे पास एक ऐसा ही मुद्दा है जो कभी-कभार होता है और यहां वह तरीका है जो मैं लेता हूं।

  1. set deadlock priority low;चयन में जोड़ें । इस गतिरोध के कारण यह क्वेरी गतिरोध का शिकार हो जाएगी।
  2. अपने एप्लिकेशन के भीतर सेटअप रीट्री लॉजिक का चयन करें यदि डेडलॉक (या टाइमआउट) के कारण विफल होने पर स्वचालित रूप से पुनः प्रयास करें, तो ब्लॉकिंग क्वेरी को पूरा करने की अनुमति देने के लिए थोड़ी देर प्रतीक्षा / नींद के बाद।

नोट: यदि आपका selectस्पष्ट मल्टी-स्टेटमेंट ट्रांजेक्शन का हिस्सा है, तो आपको पूरे लेनदेन को फिर से सुनिश्चित करना होगा, न कि केवल वह स्टेटमेंट जो विफल रहा, या फिर आप कुछ अनपेक्षित परिणाम प्राप्त कर सकते हैं। यदि यह एकल है selectतो आप ठीक हैं, लेकिन यदि यह एक लेन-देन xके nभीतर का कथन है , तो बस यह सुनिश्चित करें कि आप पुनः प्रयास के nदौरान सभी विवरणों को पुनः प्राप्त कर लें।


धन्यवाद - क्वेरी डिफ़ॉल्ट रूप से स्वचालित रूप से गतिरोध पीड़ित हैं। और हां हमारे पास पहले से ही एक मजबूत रिट्री मैकेनिज्म है।
डेल के
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.