2011-01-03 14 views
14

यह वास्तव में नोलॉक के बारे में एक विशिष्ट प्रश्न से अधिक चर्चा है।नोलोक के लिए या नोलोक के लिए नहीं, यह प्रश्न

मैंने हाल ही में एक ऐप लिया है कि लगभग हर प्रश्न (और उनमें से बहुत सारे हैं) उनके पास नोलॉक विकल्प है। अब मैं एसक्यूएल सर्वर के लिए काफी नया हूं (10 साल तक ओरेकल का इस्तेमाल किया जाता है) लेकिन फिर भी मुझे यह बहुत परेशान लगता है। तो इस सप्ताह के अंत में मैं अपने दोस्तों में से एक के साथ बात कर रहा था जो एक बड़ी ईकॉमर्स साइट चलाता है (नाम को दोषी ठहराने के लिए रोक दिया जाएगा) और वह कहता है कि उसे अपने सभी एसक्यूएल सर्वरों के साथ ऐसा करना है क्योंकि वह हमेशा डेडलॉक्स में समाप्त होगा।

क्या यह SQL सर्वर के साथ बस एक बड़ा छोटा पतन है? क्या यह डीबी डिज़ाइन में केवल एक विफलता है (मेरा तीसरा स्तर नहीं है, लेकिन इसका नज़दीक है) क्या कोई बाहर निकल के बिना SQL सर्वर ऐप चला रहा है? ये मुद्दे हैं कि ओरेकल अधिक भव्य रिकॉर्डलॉक्स के साथ बेहतर संभालता है।

क्या एसक्यूएल सर्वर बड़े भार को संभालने में सक्षम नहीं है? क्या असामान्य डेटा पढ़ने से कुछ बेहतर कामकाज है? मुझे यह जानना अच्छा लगेगा कि लोग क्या सोचते हैं।

धन्यवाद

उत्तर

13

एसक्यूएल सर्वर SQL सर्वर 2005 में snapshot isolation जोड़ा गया है, यह अभी भी ताले के लिए प्रतीक्षा किए बिना नवीनतम सही मान को पढ़ने के लिए सक्षम हो जाएगा। StackOverflow स्नैपशॉट अलगाव का भी उपयोग कर रहा है। स्नैपशॉट अलगाव स्तर ओरेकल का उपयोग करता है, उतना ही कम है, यही कारण है कि ओरेकल बॉक्स पर डेडलॉक्स बहुत आम नहीं हैं। बस अगर आप लाइन

जब READ_COMMITTED_SNAPSHOT डेटाबेस विकल्प पर सेट है पर पुस्तकें से

यह सक्रिय कर सकता है tempdb पर्याप्त जगह है करने के लिए पता होना, पढ़ प्रतिबद्ध अलगाव का उपयोग करता स्टेटमेंट प्रदान करने के लिए पंक्ति संस्करण स्तर स्थिरता पढ़ें। ऑपरेशन पढ़ें केवल SCH-S तालिका स्तर ताले और कोई पृष्ठ या पंक्ति ताले की आवश्यकता नहीं है। जब READ_COMMITTED_SNAPSHOT डेटाबेस विकल्प सेट है, जो डिफ़ॉल्ट सेटिंग है, तो अलगाव व्यवहार पढ़ें जैसा कि पहले SQL Server के संस्करणों में किया गया था। दोनों कार्यान्वयन एएनएसआई पढ़ने की अलगाव की परिभाषा को पूरा करते हैं।

+0

एक सक्रिय स्नैपशॉट के साथ, डेडलॉक में चलने की आपकी संभावना क्या है? मैं सुझाव नहीं दूंगा कि आप मुझे एक प्रतिशत दे सकते हैं, लेकिन क्या आपने कभी इसे चलाने के साथ डेडलॉक में भाग लिया है? – Limey

+0

ऐसा लगता है कि स्टैक ओवरफ्लो की समस्या ठीक हो गई है, मैंने स्वयं के साथ डेडलॉक्स नहीं देखा है, लेकिन मैं एसक्यूएल सर्वर प्रोग्रामिंग के मामले में कुछ सर्वोत्तम प्रथाओं को भी लागू करता हूं जो इसे – SQLMenace

+0

से शुरू करने के लिए कम से कम एक अच्छा विचार नहीं है ... http: // sqlblogcasts .com/ब्लॉग/टोनीरोगर्सन/संग्रह/2006/11/16/1345.aspx – gbn

4

नहीं, NOLOCK का उपयोग करने की कोई आवश्यकता नहीं है। लिंक: SO 1

लोड का सवाल है, हम जो छोटा सा परिवर्तन करने के लिए तुलना में है 35k TPS

गतिरोध ताला विवाद के कारण होता है और आमतौर पर लेन-देन में टेबल पर असंगत लिखने आदेश की वजह से प्रति सेकंड 2000 पंक्तियां के साथ सौदा। ओआरएम विशेष रूप से इस पर बकवास हैं। हम उन्हें बहुत कम बार मिलता है। एक अच्छी तरह से लिखित डीएएल भी एमएसडीएन के अनुसार पुनः प्रयास करना चाहिए।

2

पारंपरिक सामान्यीकृत OLTP वातावरण में, NOLOCK एक कोड गंध है और लगभग निश्चित रूप से एक उचित ढंग से डिज़ाइन की गई प्रणाली में अनावश्यक है।

एक आयामी मॉडल में, मैंने बहुत बड़े तथ्य और आयाम तालिकाओं को लॉक करने से बचने के लिए बड़े पैमाने पर NOLOCK का उपयोग किया जो बाद के तथ्य डेटा (और आयाम समाप्त हो रहे थे) के साथ पॉप्युलेट किए जा रहे थे। आयामी मॉडल में, तथ्यों को कभी भी एक निश्चित बिंदु के बाद कभी नहीं बदला या कभी नहीं बदला जाता है।इसी प्रकार, संदर्भित किसी भी आयाम को स्थिर भी होगा, उदाहरण के लिए, एनओएलओसीके कल के डेटा पर डेटा के लोड के दौरान डेटा लोड के दौरान आयाम समाप्ति को अवरुद्ध करने से आपके लंबे विश्लेषण ऑपरेशन को रोक देगा।

11

अगर कोई कहता है कि नोलोक के बिना उनका आवेदन हमेशा मृत हो जाता है, तो उनके प्रश्नों के साथ समस्या (संभावना से अधिक) होती है। डेडलॉक का अर्थ है कि दो लेनदेन संसाधन विवाद के कारण आगे नहीं बढ़ सकते हैं और समस्या का समाधान नहीं किया जा सकता है। एक उदाहरण:

लेनदेन ए और बी पर विचार करें दोनों उड़ान में हैं। लेनदेन ए ने तालिका एक्स में एक पंक्ति डाली है और लेनदेन बी ने तालिका वाई में एक पंक्ति डाली है, इसलिए लेनदेन ए के पास एक्स पर एक विशेष लॉक है और लेनदेन बी के पास वाई

पर एक विशेष लॉक है, अब लेनदेन ए की आवश्यकता है तालिका वाई के खिलाफ चयन करें और लेनदेन बी को तालिका X के खिलाफ एक चयन चलाने की आवश्यकता है।

दो लेनदेन मृतक हैं: एक संसाधन संसाधन वाई और बी को संसाधन एक्स की आवश्यकता है। चूंकि न तो लेनदेन आगे बढ़ने तक आगे बढ़ सकता है, इसलिए बैठना नहीं हो सकता हल किया गया: न तो संसाधन के लिए लेनदेन की मांग तब तक सब्सिडीकृत की जा सकती है जब तक अन्य लेनदेन विवाद में संसाधन पर लॉक जारी नहीं करता है (या तो रोलबैक या COMMIT द्वारा कोई फर्क नहीं पड़ता।)

एसक्यूएल सर्वर इस स्थिति की पहचान करता है और एक लेन-देन का चयन करता है या दूसरा डेडलॉक पीड़ित के रूप में चुनता है, जो लेनदेन और रोल वापस करता है, अन्य लेनदेन को अपने अनुमानित पूरा होने के लिए स्वतंत्र छोड़ देता है।

वास्तविक जीवन में डेडलॉक्स दुर्लभ हैं (आईएमएचओ)। एक से

  • उन्हें rectifies सुनिश्चित करना है कि लेन-देन गुंजाइश संभव के रूप में छोटा है, कुछ एसक्यूएल सर्वर स्वचालित रूप से करता है, और
  • सुनिश्चित करना है कि लेन-देन का उपयोग संसाधनों (SQL सर्वर के डिफ़ॉल्ट लेन-देन गुंजाइश COMMIT एक अंतर्निहित के साथ एक एकल बयान है) एक ही अनुक्रम में। उपर्युक्त उदाहरण में, यदि लेनदेन ए और बी दोनों एक ही अनुक्रम में संसाधन एक्स और वाई लॉक करते हैं, तो कोई डेडलॉक नहीं होगा।

टाइमआउट

टाइमआउट, दूसरे हाथ पर, जब एक सौदा इसकी प्रतीक्षा समय से अधिक है और संसाधन विवाद की वजह से वापस लुढ़का हुआ है होता है। उदाहरण के लिए, लेनदेन ए को संसाधन एक्स की आवश्यकता होती है। संसाधन एक्स को लेनदेन बी द्वारा बंद कर दिया जाता है, इसलिए लेनदेन ए लॉक जारी होने की प्रतीक्षा करता है। यदि लॉक टाइमआउट सीमा के भीतर लॉक जारी नहीं किया जाता है, तो प्रतीक्षा लेनदेन निरस्त हो जाता है और वापस लुढ़का जाता है। प्रत्येक क्वेरी में इसके साथ जुड़े एक क्वेरी टाइमआउट होता है (डिफ़ॉल्ट मान 30 है, मुझे विश्वास है), जिसके बाद लेनदेन निरस्त हो जाता है और वापस लुढ़का जाता है। क्वेरी टाइमआउट 0s पर सेट किया जा सकता है, इस स्थिति में SQL सर्वर क्वेरी को हमेशा के लिए प्रतीक्षा करने देगा।

शायद यही वह बात है जिसके बारे में वे बात कर रहे हैं। मेरे अनुभव में, इस तरह के टाइमआउट आमतौर पर बड़े डेटाबेस में होते हैं जब बड़ी बैच नौकरियां एक ही लेनदेन में हजारों और हजारों रिकॉर्ड अपडेट कर रही हैं, हालांकि वे ऐसा कर सकते हैं क्योंकि एक लेनदेन लंबा हो जाता है (क्वेरी एबलाइज़र में अपने उत्पादन डेटाबेस से कनेक्ट करें, BEGIN निष्पादित करें ट्रांज़ेक्शन, क्वेरी विश्लेषक में अक्सर हिट टेबल में एक पंक्ति को अपडेट करें और रोलबैक या कम्युनिकेशन ट्रांज़ेक्शन निष्पादित किए बिना दोपहर के भोजन पर जाएं और देखें कि उत्पादन डीबीए आपके लिए एपीएस ** टी पर कितना समय लेता है। यदि आपका है कि क्या करने जा रहा है, बस: कैसे मैं यह जानता हूँ मुझे मत पूछो)

टाइमआउट इस तरह की है NOLOCK के सभी प्रकार के साथ पूरी तरह से निर्दोष एसक्यूएल splattering में आम तौर पर क्या परिणाम

[टिप संकेत एसईटी ट्रांज़ेक्शन इशोलेशन लेवल को अपने संग्रहीत प्रक्रिया में पहले बयान के रूप में प्रस्तुत किया गया है और इसके साथ किया गया है।]

इस दृष्टिकोण के साथ समस्या (NOLOCK/पढ़ा गया अनौपचारिक) यह है कि आप अन्य लेनदेन से असामान्य डेटा पढ़ सकते हैं: सामान अधूरा है या जो बाद में लुढ़का हो सकता है, इसलिए आपकी डेटा अखंडता संचित है। आप उच्च स्तर की बोगोसिटी वाले डेटा के आधार पर एक बिल भेज रहे हैं।

मेरा सामान्य नियम यह है कि किसी को यथासंभव तालिका संकेतों के उपयोग से बचना चाहिए। एसक्यूएल सर्वर और इसके क्वेरी ऑप्टिमाइज़र को अपनी नौकरियां करने दें।

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

एक मोन्डो सम्मिलित कथन में दस लाख पंक्तियों को डालने के बजाय, स्वतंत्र भाग में काम करें और स्वतंत्र रूप से प्रत्येक खंड को प्रतिबद्ध करें। यदि 999,000 पंक्तियों को संसाधित करने के बाद आपकी मिलियन पंक्ति सम्मिलित हो जाती है, तो पूरा काम खो जाता है (उल्लेख नहीं है कि रोलबैक अब * टीएच हो सकता है, और तालिका अभी भी रोलबैक के दौरान बंद है।) यदि आप ब्लॉक में लाखों पंक्तियां डालते हैं प्रत्येक ब्लॉक के बाद प्रत्येक 1000 पंक्तियों में से प्रत्येक, आप लॉक विवाद से बचते हैं जो डेडलॉक्स का कारण बनता है, क्योंकि ताले प्राप्त किए जाएंगे और जारी किए जाएंगे और चीजें आगे बढ़ती रहेंगी। यदि 1000 पंक्तियों के 99 9 वें ब्लॉक में कुछ दक्षिण में जाता है, और लेनदेन निरस्त हो जाता है और वापस लुढ़का जाता है, तो आपको अभी भी 998,000 पंक्तियां मिलती हैं; आपने केवल काम की 1000 पंक्तियां खो दी हैं। पुनरारंभ/पुनः प्रयास करना बहुत आसान है।

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

चाहे आप कार्यात्मक रूप से नोलोक/पढ़ने के उपयोग से बचने से बच सकते हैं, अंतर्निहित डेटाबेस (और संगठन के संगठन की संस्कृति) को मारने वाली प्रक्रियाओं की प्रकृति पर पूरी तरह से निर्भर है।

स्वयं, मैं जितना संभव हो उतना उपयोग से बचने की कोशिश करता हूं।

उम्मीद है कि इससे मदद मिलती है।

+0

धन्यवाद! मुझे लगता है कि चर्चा के लिए अच्छी जानकारी मिलती है। – Limey

1

आपको अपरिवर्तनीय तालिका पर केवल nolock का उपयोग करना चाहिए। बेशक, यह वही होगा जैसा पढ़ा गया स्नैपशॉट पढ़ें। स्नैपशॉट के बिना, आप केवल साझा लॉक को लागू करने के लिए समय निकाल रहे हैं, और उसके बाद इसे हटाने के लिए, जो ज्यादातर मामलों के लिए आवश्यक नहीं है।

एक बदलती हुई तालिका के लिए ... किसी भी लॉक का मतलब यह नहीं है कि लेनदेन से पहले अपनी पंक्तियों को अपडेट करने से पहले कोई पंक्ति प्राप्त हो। आप भूत डेटा प्राप्त कर सकते हैं क्योंकि डेटा पेज विभाजित होते हैं, या यहां तक ​​कि इंडेक्स पेज भी विभाजित होते हैं। या कोई डेटा नहीं। वह अकेला मुझे डराता है, लेकिन मुझे लगता है कि और भी परिदृश्य हो सकते हैं जहां आपको गलत डेटा मिल जाता है।

बेशक, किसी न किसी अनुमान के लिए नोलॉक या किसी प्रक्रिया पर जांच करने के लिए उचित हो सकता है।

अंगूठे का मूल नियम - यदि आप डेटा के बारे में परवाह करते हैं, और डेटा बदल रहा है, तो NoLOCK का उपयोग न करें।

+0

नोगिन्स - यह वह डेटा नहीं है जिसे तुच्छ होना चाहिए; यह डेटा का अनुरोध है। मैंने दो उदाहरण दिए - अनुमान, या किसी प्रकार का विचार प्राप्त करने के लिए जहां आप हैं। तो डेटा/प्रक्रिया हो सकती है, और पूरी तरह से आवश्यक हो सकता है। लेकिन पढ़ने के लिए ये विशेष उपयोग के मामले नोलॉक के साथ ऐसा कर सकते हैं क्योंकि आप एक नूक या कुछ डिजाइन करने के लिए डेटा का उपयोग नहीं करेंगे। बस चेक इन –

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