2012-02-19 16 views
7

मैं innodb लेनदेन के बारे में एक मैनुअल पढ़ रहा हूँ लेकिन फिर भी, मेरे लिए बहुत अस्पष्ट चीजें हैं। उदाहरण के लिए, मैं काफी निम्न व्यवहार करने के लिए समझ में नहीं आता: अबinno डीबी अलगाव स्तर और लॉकिंग

-- client 1        -- client 2 
mysql> create table simple (col int) 
     engine=innodb; 

mysql> insert into simple values(1); 
Query OK, 1 row affected (0.00 sec) 

mysql> insert into simple values(2); 
Query OK, 1 row affected (0.00 sec) 

mysql> select @@tx_isolation;                
+-----------------+                   
| @@tx_isolation | 
+-----------------+ 
| REPEATABLE-READ |                   
+-----------------+ 

mysql> begin;          
Query OK, 0 rows affected (0.01 sec)    
             mysql> begin; 
             Query OK, 0 rows affected (0.00 sec) 

mysql> update simple set col=10 where col=1; 
Query OK, 1 row affected (0.00 sec) 
Rows matched: 1 Changed: 1 Warnings: 0 

             mysql> update simple set col=42 where col=2; 
             -- blocks 

, अंतिम अद्यतन आदेश (ग्राहक 2 में) इंतजार कर रहा है। मैं आदेश को निष्पादित करने की अपेक्षा करता हूं क्योंकि मुझे लगता है कि केवल पंक्ति 1 लॉक है। व्यवहार वही है भले ही क्लाइंट 2 में दूसरा आदेश insert है। क्या कोई इस उदाहरण के पीछे लॉकिंग पृष्ठभूमि का वर्णन कर सकता है (कहां और क्यों ताले)?

+1

** के बारे में पढ़ें ** 'दोहराया गया पढ़ें ** **: [लेनदेन स्तर] (http://dev.mysql.com/doc/refman/5.5/en/set-transaction.html):' पढ़ने को लॉक करने के लिए (साझा मोड में अद्यतन या लॉक के साथ चुनें), अद्यतन, और हटाएं कथन, लॉकिंग ** इस बात पर निर्भर करता है कि कथन एक अद्वितीय खोज स्थिति ** या एक श्रेणी-प्रकार की खोज स्थिति के साथ एक अद्वितीय अनुक्रमणिका का उपयोग करता है या नहीं। ... ' –

उत्तर

9

InnoDB निम्न प्रकार के ताले को निम्नानुसार सेट करता है।

  • का चयन करें ... से एक सुसंगत पढ़ने, डेटाबेस का एक स्नैपशॉट पढ़ रहे हैं और जब तक लेन-देन अलगाव स्तर serializable के लिए सेट है कोई ताले की स्थापना है। सर्जिकल स्तर के लिए, खोज सेट इंडेक्स रिकॉर्ड पर अगली-कुंजी ताले साझा करता है जो इसे मुठभेड़ करता है।

  • चुनें ... से ... शेयर मोड में लॉक सभी इंडेक्स पर खोज-पड़ताल के बाद के प्रमुख लॉक साझा करता है।

  • सूचकांक के लिए खोज मुठभेड़ रिकॉर्ड, चयन ... से ... अद्यतन के लिए अन्य सत्रों को चुनने से ब्लॉक ... से ... साझा मोड में लॉक या कुछ लेनदेन अलगाव स्तर में पढ़ने से। लगातार पढ़ने से पढ़ने वाले दृश्यों में मौजूद रिकॉर्ड्स पर सेट किए गए किसी भी ताले को अनदेखा कर दिया जाएगा।

  • अद्यतन ... जहां ... खोज मुठभेड़ों के प्रत्येक रिकॉर्ड पर एक विशेष अगली कुंजी लॉक सेट करता है।

  • से हटाएं ... जहां ... खोज मुठभेड़ के प्रत्येक रिकॉर्ड पर एक विशेष अगली कुंजी लॉक सेट करता है।

  • INSERT डाली गई पंक्ति पर एक विशेष लॉक सेट करता है। यह लॉक एक इंडेक्स-रिकॉर्ड लॉक है, न कि अगली-कुंजी लॉक (यानी, कोई अंतर नहीं है) और अन्य सत्रों को सम्मिलित पंक्ति से पहले अंतर में डालने से नहीं रोकता है।

InnoDB रिकॉर्ड स्तर के ताले के कई प्रकार होते हैं:

  • रिकार्ड ताला: यह एक सूचकांक रिकॉर्ड पर एक ताला है।

  • गैप लॉक: यह इंडेक्स रिकॉर्ड के बीच एक अंतर पर लॉक है, या पहले या पिछले इंडेक्स रिकॉर्ड के बाद अंतराल पर लॉक है।

  • अगला कुंजी लॉक: यह इंडेक्स रिकॉर्ड पर रिकॉर्ड लॉक और इंडेक्स रिकॉर्ड से पहले अंतर पर एक अंतर लॉक का संयोजन है।

अधिक देखें:

Avoiding the Phantom Problem Using Next-Key Locking

Avoiding deadlock

+0

अच्छा अवलोकन लेकिन मुझे आश्चर्य है कि आपके द्वारा लिखे गए इंडेक्स में कैसे फिट बैठता है। सूचकांक की मौजूदगी मेरे उदाहरण में व्यवहार को क्यों बदलती है? – clime

+2

अगला-कुंजी लॉकिंग अंतराल लॉकिंग के साथ इंडेक्स-पंक्ति लॉकिंग को जोड़ती है। InnoDB पंक्ति-स्तर लॉकिंग को इस तरह से करता है कि जब यह किसी तालिका अनुक्रमणिका को खोजता या स्कैन करता है, तो यह इंडेक्स रिकॉर्ड पर साझा या अनन्य ताले सेट करता है। इसके अलावा, इंडेक्स रिकॉर्ड पर एक अगली-कुंजी लॉक भी उस इंडेक्स रिकॉर्ड से पहले "अंतर" को प्रभावित करता है। यही है, एक अगली कुंजी लॉक एक इंडेक्स-रिकॉर्ड लॉक है और इंडेक्स रिकॉर्ड से पहले के अंतराल पर एक अंतर लॉक है। –

0

ypercube यह सही है। विशेष रूप से, इस स्थिति में उपयोग की जाने वाली एक अद्वितीय अनुक्रमणिका के बिना, यह प्रभावित होने वाली एकल पंक्ति से अधिक लॉक हो जाएगा।

व्यवहार जैसा कि आप उम्मीद देखने के लिए, यह करने के लिए अपनी मेज निर्माण बदलने के लिए:

create table simple (col int unique) ENGINE=InnoDB; 

col मैदान पर अद्वितीय सूचकांक यह केवल प्रभावित पंक्ति लॉक करने के लिए अनुमति देगा।

+0

जैसा कि मैंने पाया है, वहां एक अनुक्रमणिका होने की आवश्यकता है लेकिन इसे अद्वितीय होने की आवश्यकता नहीं है। – clime

+0

आह, जब मैंने पढ़ा कि यह एक अद्वितीय खोज स्थिति के साथ एक अद्वितीय इंडेक्स का उपयोग करता है, तो मैंने इसे 'अद्वितीय' इंडेक्स के रूप में लिया, लेकिन उनके पास एकल, विशिष्ट के रूप में अद्वितीय होना चाहिए। – kbenson

+0

क्या लिखा गया ypercube (पूरी तरह से) प्रासंगिक नहीं है। यदि कोई अनूठी अनुक्रमणिका और अद्वितीय खोज स्थिति है, तो रिकॉर्ड-लॉक का उपयोग अगली-कुंजी ताले के बजाय किया जाता है। मेरे उदाहरण में, इससे कोई फर्क नहीं पड़ता कि रिकॉर्ड लॉक या अगली-कुंजी ताले का उपयोग किया जाता है क्योंकि केवल पहले अंतर से लॉक होने वाला अंतर यह है कि 1 से पहले और दूसरा अपडेट संदर्भ 2. महत्वपूर्ण है कि एक (y) अनुक्रमणिका क्योंकि अद्यतन केवल लक्ष्य रिकॉर्ड को लॉक नहीं करता है, यह लक्ष्य रिकॉर्ड_ के लिए खोज के दौरान सामने आने वाले सभी रिकॉर्ड्स को लॉक करता है। कोई अनुक्रमणिका => पूर्ण स्कैन => सभी रिकॉर्ड लॉक। – clime

0

"अनुक्रमणिका के लिए रिकॉर्ड खोज मुठभेड़ों, का चयन करें ... से ... अद्यतन ब्लॉक का चयन करने से अन्य सत्र के लिए .. ... से साझा मोड में लॉक या कुछ लेन-देन अलगाव स्तरों में पढ़ने से। लगातार पढ़े गए पढ़ने के रिकॉर्ड में मौजूद रिकॉर्ड्स पर सेट किए गए किसी भी ताले को अनदेखा कर देगा "

उन कुछ ताले क्या हैं जिन्हें अद्यतन के लिए चयन के साथ लागू किया जा सकता है ताकि अन्य सत्र लॉक रिकॉर्ड न पढ़ सकें?

+0

क्षमा करें, यह कोई जवाब नहीं है। एक अलग सवाल पोस्ट करने पर विचार करें। – Beryllium

+0

stalkoverflow लोग मुझे इसे एक नए प्रश्न के रूप में पोस्ट करने की अनुमति नहीं दे रहे हैं – ravi

+0

mysql में ऐसा कोई लॉक नहीं है, [यह जवाब] देखें (http://stackoverflow.com/a/21792907/3576887) एक कामकाज के लिए – elipoultorak