2009-05-27 14 views
107

क्वेरी:MySQL में लॉकिंग के बिना चुनने का कोई तरीका?

SELECT COUNT(online.account_id) cnt from online; 

लेकिन ऑनलाइन टेबल भी एक घटना से संशोधित किया गया है, इसलिए अक्सर मैं ताला show processlist चलाकर देख सकते हैं।

क्या MySQL में कोई व्याकरण है जो चुनिंदा कथन को ताले के कारण नहीं बना सकता है?

और मैं उपरोक्त उल्लेख करना भूल गया हूं कि यह एक MySQL गुलाम डेटाबेस पर है।

बाद मैं my.cnf:transaction-isolation = READ-UNCOMMITTED गुलाम में जोड़ा त्रुटि के साथ पूरा करेगा:

Error 'Binary logging not possible. Message: Transaction level 'READ-UNCOMMITTED' in InnoDB is not safe for binlog mode 'STATEMENT'' on query 

तो, वहाँ यह करने के लिए एक संगत तरीका है?

+2

अन्य लोगों के लिए जो इस प्रश्न का सामना करते हैं और उनके तालिकाओं पर ताले के साथ कठिन समय हो रहा है: कैसे mySQL ताले का उपयोग करता है आंतरिक रूप से स्टोरेज इंजन पर निर्भर करता है। नीचे @zombat द्वारा जवाब पढ़ें। –

उत्तर

11

आप MySQL मैनुअल के this page पढ़ना चाह सकते हैं। एक टेबल लॉक कैसे हो जाती है यह निर्भर करता है कि यह किस प्रकार की तालिका है।

माईसैम बहुत अधिक पढ़ने की गति प्राप्त करने के लिए टेबल लॉक का उपयोग करता है, लेकिन यदि आपके पास अद्यतन विवरण प्रतीक्षा है, तो भविष्य के चयन अपडेट के पीछे कतारबद्ध होंगे।

इनो डीबी टेबल पंक्ति-स्तर लॉकिंग का उपयोग करते हैं, और आपके पास एक अद्यतन के पीछे पूरी तालिका लॉक नहीं होगी। InnoDB से जुड़े अन्य प्रकार के लॉकिंग मुद्दे हैं, लेकिन आपको लगता है कि यह आपकी आवश्यकताओं के अनुरूप है। - यह लगातार पढ़ने के लिए (कोई-लॉकिंग मोड) का उपयोग करता है का चयन करता है "कि अद्यतन या शेयर मोड में लॉक के लिए निर्दिष्ट नहीं करते के लिए तालिका InnoDB है

If you acquire a table lock explicitly with LOCK TABLES, you can request a READ LOCAL lock rather than a READ lock to enable other sessions to perform concurrent inserts while you have the table locked.

+1

"सेट ट्रांज़ेक्शन इज़ोलेशन लेवल अनकॉम्मिटेड पढ़ा जाएगा" माईसाम टेबल के लिए काम करेगा? – omg

+5

माईसाम टेबल किसी भी रूप में लेनदेन का समर्थन नहीं करते हैं। एक लेनदेन संबंधी क्वेरी एक MyISAM तालिका पर चलती है, इसलिए ऊपर उल्लिखित क्वेरी निष्पादित होगी, लेकिन इसका कोई प्रभाव नहीं पड़ता है। – zombat

+1

फिर MyISAM के मामले में SELECTS कतार में आने से बचने के लिए मैं क्या कर सकता हूं? – omg

0
this संदर्भ से

यदि innodb_locks_unsafe_for_binlog विकल्प सेट किया गया है और लेनदेन का अलगाव स्तर SERIALIZABLE पर सेट नहीं है। इस प्रकार, चयनित तालिका से पढ़ने वाली पंक्तियों पर कोई ताला सेट नहीं है "।

13

उपयोग

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED.

संस्करण 5.0 डॉक्स here हैं।

संस्करण 5.1 डॉक्स here हैं।

+2

धन्यवाद, मुझे लगता है कि यह निकट है, लेकिन यह कथन कब तक प्रभावी होगा? मैं इस कथन का उपयोग एक PHP प्रोग्राम में करने जा रहा हूं, और सबसे अच्छा रीसेट ट्रांसलेशन इज़ोलेशन लेवल रीसेट हो जाना चाहिए एक बार क्वेरी समाप्त हो जाने पर – omg

2

आपके टेबल प्रकार के आधार पर, लॉकिंग अलग-अलग प्रदर्शन करेगी, लेकिन एक चयन गणना भी होगी। MyISAM तालिकाओं के लिए तालिका से एक साधारण चयन गणना (*) तालिका को लॉक नहीं करना चाहिए क्योंकि यह रिकॉर्ड गणना खींचने के लिए मेटा डेटा तक पहुंचता है। इनोडब को अधिक समय लगेगा क्योंकि रिकॉर्ड को गिनने के लिए इसे स्नैपशॉट में टेबल को पकड़ना है, लेकिन इसे लॉकिंग नहीं करना चाहिए।

आपको कम से कम concurrent_insert 1 (डिफ़ॉल्ट) पर सेट करना चाहिए। फिर, यदि तालिका भरने के लिए डेटा फ़ाइल में कोई "अंतराल" नहीं है, तो प्रविष्टियों को फ़ाइल में जोड़ा जाएगा और चयन और INSERT एक साथ MyISAM तालिकाओं के साथ हो सकता है। ध्यान दें कि रिकॉर्ड हटाने से डेटा फ़ाइल में "अंतर" होता है जो भविष्य के आवेषण और अपडेट से भरने का प्रयास करेगा।

यदि आप शायद ही कभी रिकॉर्ड्स हटाते हैं, तो आप समवर्ती_इनर्ट 2 के बराबर सेट कर सकते हैं, और डेटा फ़ाइल के अंत में आवेषण हमेशा जोड़े जाएंगे। फिर चयन और आवेषण एक साथ हो सकते हैं, लेकिन आपकी डेटा फ़ाइल कभी भी छोटी नहीं होगी, इससे कोई फर्क नहीं पड़ता कि आप कितने रिकॉर्ड हटाते हैं (सभी रिकॉर्ड को छोड़कर)।

नीचे लाइन, यदि आपके पास बहुत सारे अपडेट हैं, एक टेबल पर आवेषण और चयन करते हैं, तो आपको इसे InnoDB बनाना चाहिए। हालांकि आप सिस्टम में टेबल प्रकारों को स्वतंत्र रूप से मिश्रित कर सकते हैं।

130

मिले शीर्षक से एक लेख "NOLOCK के साथ MySQL"

https://web.archive.org/web/20100814144042/http://sqldba.org/articles/22-mysql-with-nolock.aspx

MSSQL में आप निम्नलिखित करना होगा:

SELECT * FROM TABLE_NAME WITH (nolock) 

और MySQL बराबर

SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ; 
SELECT * FROM TABLE_NAME ; 
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ ; 

है संपादित करें

Michael Mior सुझाव दिया निम्नलिखित (टिप्पणियों से)

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ; 
SELECT * FROM TABLE_NAME ; 
COMMIT ; 
+6

धन्यवाद, इसलिए यह इनोडब के लिए काम करेगा, लेकिन अगर मायिसम? – omg

+41

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

+3

बस एक नोट, वह लिंक मर चुका है ... :( – longda

1

का चयन करता है सामान्य रूप से किसी भी ताला है कि आप InnoDB टेबल पर के बारे में परवाह नहीं करते हैं। डिफ़ॉल्ट लेनदेन अलगाव स्तर का अर्थ है कि सामान लॉक न करें का चयन करें।

बेशक विवाद अभी भी होता है।

+0

मुझे पता है कि यह पोस्ट पुराना है, लेकिन यह उत्तर बहुत सामान्य है, और केवल कभी-कभी सच है। Http://dev.mysql.com/doc/refman/5.0/en/innodb-locks-set.html देखें। अलगाव स्तर के आधार पर, ताले निश्चित रूप से पढ़ने के लिए _are_ अधिग्रहण किया जाता है। विशेष रूप से, इस मामले में, पोस्टर प्रतिकृति डेटाबेस से निपट रहा है और स्पष्ट रूप से कहा है कि वह वास्तव में ताले देखने के लिए 'शो प्रक्रिया सूची' का उपयोग कर सकता है। इसलिए यह मानना ​​सुरक्षित है कि वास्तव में ताले लगाए जा रहे हैं। – Craig

+1

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

+1

_ हमेशा के लिए हमेशा? क्या होगा यदि लेनदेन अलगाव स्तर serializable पर सेट है, या चयन कथन शेयर मोड में लॉक का उपयोग करता है और autocommit अक्षम है? मुझे पता है कि कई (अधिकांश/सभी?) डेटाबेस सर्वर अब सही क्रमिकरण के बजाय डिफ़ॉल्ट रूप से स्नैपशॉट अलगाव का उपयोग करते हैं, लेकिन क्या सीरियलज़ेबल पढ़ने को मजबूर करने के लिए अभी भी कभी-कभी औचित्य नहीं हैं? लेकिन ऐसा लगता है जैसे आप कह रहे थे कि सभी दूरस्थ सामान्य मामलों में, MySQL में डिफ़ॉल्ट स्थितियां अन्य धागे को प्रभावित करने वाले पढ़ने वाले ताले का कारण नहीं बनती हैं, इसलिए किसी समस्या के बारे में चिंता न करें जो आपके पास नहीं है? मैंने अपने डाउनवोट, बीटीडब्ल्यू को पूर्ववत करने की कोशिश की। क्षमा करें ... – Craig

0

mysql में गंदे पढ़ने को सक्षम करने का एक और तरीका संकेत जोड़ना है: साझा मोड में लॉक साझा करें * साझा मोड में टैबलेट लॉक से चुनें;

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