टैब्लॉक संकेत गतिरोध को ट्रिगर करता है


10

मैं दो डेटा सेट सम्मिलित कर रहा था, न्यूनतम लॉगिंग का उपयोग करके, एक खाली हीप तालिका में दो समानांतर SQL टास्क के माध्यम से समानांतर में चल रहा है और निम्न फॉर्म के एसक्यूएल के साथ।

INSERT INTO Table (TABLOCK) SELECT FROM ...

जॉब थोड़ा रुकने के बाद, SQL कार्य में से एक एक डेडलॉक शिकार बन गया। नीचे डेडलॉक ग्राफ का XML आउटपुट है।

क्या कोई समझा सकता है कि हुड के नीचे क्या हो रहा था?

  <resource-list>
   <objectlock lockPartition="0" objid="1586156746" subresource="FULL" dbid="7" objectname="dbo.TargetTable" id="lock7374a00" mode="IX" associatedObjectId="1586156746">
    <owner-list>
     <owner id="process9609dc8" mode="Sch-S"/>
     <owner id="process9609dc8" mode="IX"/>
    </owner-list>
    <waiter-list>
     <waiter id="process5e13048" mode="X" requestType="convert"/>
    </waiter-list>
   </objectlock>
   <objectlock lockPartition="0" objid="1586156746" subresource="FULL" dbid="7" objectname="dbo.TargetTable" id="lock7374a00" mode="IX" associatedObjectId="1586156746">
    <owner-list>
     <owner id="process5e13048" mode="Sch-S"/>
     <owner id="process5e13048" mode="IX"/>
    </owner-list>
    <waiter-list>
     <waiter id="process9609dc8" mode="X" requestType="convert"/>
    </waiter-list>
   </objectlock>
  </resource-list>

चीजें बहुत पेचीदा हो जाती हैं क्योंकि मैंने पाया है कि ज्यादातर मामलों में दो एक्सक्यूटाइल एसक्यूएल टास्क समानांतर रूप से सफलतापूर्वक चल सकते हैं। नीचे आज़माएँ:

Create table dbo.TablockInsert (c1 int, c2 int, c3 int)

--then issue the script in two Execute Sql Task in parallel you won't fail:
insert into dbo.TablockInsert(TABLOCK) SELECT 1, 1, 1

चूंकि एकमात्र अंतर SELECT ... FROM ... स्टेटमेंट, SELECT ... FROM ... स्टेटमेंट की तरह दिखता है, जिससे यहां लॉक इन पर प्रभाव पड़ सकता है?


गतिरोध को रोकने के लिए आप TABLOCK के बजाय TABLOCKX निर्दिष्ट कर सकते हैं। हालाँकि यह भी तालिका तक पहुँच को क्रमबद्ध करेगा, फिर भी आपको न्यूनतम लॉगिंग मिलेगी।
डेन गुज़मैन

जवाबों:


8

डाटा लोड हो रहा है प्रदर्शन गाइड एसक्यूएल सर्वर 2008 के लिए लिखा गया था, लेकिन जहाँ तक मैं बता सकता है माइक्रोसॉफ्ट ढेर के लिए इस क्षेत्र में किसी भी सुधार किए नहीं किया है। यहां आपके लोडिंग परिदृश्य के लिए एक उद्धरण है:

थोक लोड हो रहा है एक खाली, गैरपारंपरिक तालिका

एक गैर-संचालन तालिका में डेटा लोड करना, जबकि एक सरल ऑपरेशन, कई तरीकों से अनुकूलित किया जा सकता है।

...

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

इस परिदृश्य में, INSERT… SELECT और SELECT INTO दोनों में एक खामी है। ये दोनों ऑपरेशन गंतव्य पर एक अनन्य (एक्स), टेबल लेवल लॉक लेते हैं। इसका मतलब यह है कि स्केलेबिलिटी को सीमित करते हुए, एक निश्चित समय पर केवल एक बल्क लोड ऑपरेशन ही चल सकता है। हालाँकि, BCP, BULK INSERT, और इंटीग्रेशन सर्विसेज बल्क अपडेट (BU) लॉक लेने में सक्षम हैं - यदि आप TABLOCK संकेत निर्दिष्ट करते हैं।

महत्वपूर्ण हिस्सा यह है कि आपको बीयू लॉक नहीं मिलता है INSERT ... SELECT। आपको टेबल पर हमेशा एक विशेष लॉक मिलेगा, इसलिए INSERTएक समय में केवल एक ही चल सकता है।

टिप्पणियों में आपने कहा था कि आप 100k पंक्तियों या उससे कम सम्मिलित करेंगे और आवेषण के दौरान अन्य प्रक्रियाएं तालिकाओं पर नहीं चलेंगी। डेटाबेस में दो INSERT प्रश्न भेजते समय मैं उम्मीद करूंगा कि तीन चीजों में से एक:

  1. एक इन्सर्ट पहले चलता है और दूसरा इन्सर्ट ब्लॉक करता है। जब तक पहला इंसर्ट नहीं किया जाता तब तक दूसरा इंसर्ट इंतजार करता है।
  2. दूसरा इंसर्ट शुरू होने से पहले एक इंसर्ट खत्म हो जाता है। कोई स्पष्ट अवरोध नहीं है, लेकिन वे समवर्ती रूप से नहीं चलते हैं।
  3. आपको एक गतिरोध मिलता है और केवल एक इन्सर्ट सफलतापूर्वक पूरा होता है।

सभी मामलों में आप या तो लाभान्वित होते हैं या TABLOCKXक्वेरी में संकेत जोड़कर चोट नहीं पहुंचाते हैं , इसलिए गतिरोध के आसपास काम करने की मेरी सिफारिश है। यदि आप यह जानना चाहते हैं कि कभी-कभी गतिरोध क्यों होता है तो आपको इसके लिए एक और उत्तर देखने की आवश्यकता होगी।

एक अलग परिदृश्य के लिए जिसमें आपको वास्तव में समानांतर डालने की आवश्यकता होती है, बीयू मुद्दे के आसपास काम करने के दो तरीके हैं अपने ढेर को विभाजित करना और प्रत्येक सत्र को एक अलग विभाजन में सम्मिलित करना या BCP, BULK INSERT, या एकीकरण सेवाओं के माध्यम से अपना डेटा लोड करना। ।


उत्तर के लिए धन्यवाद, लेकिन जिस स्थिति का मुझे गतिरोध का सामना करना पड़ा, वह अब तक मेरे पास एकमात्र मामला है। ज्यादातर मामलों के लिए जब आप INSERT INTO with (TABLOCK) जारी करते हैं, तो समानांतर में नौकरी से असफलता नहीं मिलेगी। BTW, मैं SQL सर्वर 2008 R2 का उपयोग कर रहा हूं। मैंने अपने प्रश्न में एक सफल उदाहरण जोड़ा है।
SqlWhale

@ मामलों में यह संभवत: विफल नहीं होता है क्योंकि वे वास्तव में क्रमिक रूप से चल रहे हैं। हो सकता है कि आप केवल इस मुद्दे को हिट करते हैं जब योजना संकलन के लिए एक निश्चित शुरुआत का समय होता है।
मार्टिन स्मिथ

@MartinSmith प्रश्न जहाँ मुझे प्रोजेक्ट पर समस्या का सामना करना पड़ा है, वह SELECT 1 उदाहरण की तुलना में बहुत अधिक जटिल है, जिसके लिए अधिक संकलन ओवरहेड की आवश्यकता होती है, लेकिन यह केवल कुछ तालिकाओं से पढ़ा जा रहा है। मैं अधिक जटिल प्रश्नों द्वारा इस प्रकार के गतिरोध को पुन: उत्पन्न करने का प्रयास कर रहा हूं।
SqlWhale

@TecKnowNothing आप कितनी पंक्तियाँ डालते हैं? प्रक्रिया प्रति दिन कितनी बार चलती है? क्या अन्य क्वेरीज़ डेटा लोड होने के दौरान तालिका से चयन करें?
जो ओबिश

@JoeObish 1. मुझे नहीं लगता कि # पंक्तियों का मुद्दा यहां है, हमारे पास प्रत्येक प्रश्न के लिए केवल 4000 - 70000 हैं, लेकिन वे घन उपयोग के लिए अत्यधिक एकत्रित डेटा हैं। 2. यह अभी भी परीक्षण चरण के तहत है, प्रति दिन एक बार चलना चाहिए। 3. कोई और लक्ष्य तालिका से पढ़ रहा है।
SqlWhale

4

आप dbo.TargetTableदो सत्रों से प्रवेश कर रहे हैं और दोनों TABLOCKसंकेत का उपयोग कर रहे हैं। दोनों को पकड़ना process9609dc8और process5e13048पकड़ना Sch-Sऔर IXलॉक करना जो एक दूसरे के साथ संगत हैं इसलिए दोनों प्रक्रिया एक ही समय में पकड़ सकते हैं। लेकिन दोनों IXलॉक को Exclusive Xटाइप में बदलना चाहते हैं । Xताले एक दूसरे के साथ संगत नहीं हैं। इसलिए, SQL सर्वर ने एक-दूसरे के लिए प्रतीक्षा करने के बजाय गतिरोध पीड़ित के रूप में सत्र में से एक को चुना।

बुनियादी गतिरोध की जानकारी।

लॉक संगतता (डेटाबेस इंजन) चार्ट।

डेडलॉक का पता लगाना और समाप्त करना।

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