@RolandoMySQLDBA ने सवाल का सटीक उत्तर दिया है ... लेकिन उन्होंने यह भी बताया कि उनका समाधान "त्वरित-और-गंदा" था।
और यह एक बहुत ही सच्चा कथन है। :)
जो चीज़ मुझे यहाँ चिंतित करती है, वह उस उत्तर के साथ नहीं है, बल्कि यह है कि मूल प्रश्न गलत धारणा बनाता है:
मैं दो सर्वरों को क्वेरी कर सकता हूं और पूछ सकता हूं कि कौन सा एक मास्टर है, फिर उस पर सभी प्रश्न करें।
समस्या यह है कि MySQL प्रतिकृति में, मास्टर वास्तव में कभी भी जागरूक नहीं होता है कि वह मास्टर है।
"मास्टर को पदोन्नति" की अवधारणा वास्तव में MySQL अतुल्यकालिक प्रतिकृति में एक अवधारणा नहीं है। MySQL सर्वर को मास्टर रोल में "प्रमोट करना" कुछ ऐसा होता है जो "MySQL सर्वर के बाहरी" से होता है, जैसा कि कुछ ऐसा होता है, जो MySQL सर्वर के लिए "आंतरिक" होता है।
किसी भी तरह के सर्वर प्रोविजनिंग के द्वारा "मास्टर टू प्रमोशन" नहीं किया जाता है, क्योंकि, तकनीकी रूप से, हर MySQL सर्वर जिसमें बाइनरी लॉगिंग सक्षम है, एक मास्टर है, भले ही उसके पास कभी गुलाम न हो। SHOW MASTER STATUS
ठीक उसी तरह काम करता है और ठीक वैसा ही परिणाम देता है, गुलाम या नहीं, और 2 गुलामों वाला एक मास्टर 1 गुलाम या 0 गुलामों के साथ एक मास्टर से कम या ज्यादा नहीं होता है। इसी तरह, एक मास्टर जिसके दास सभी ऑफ़लाइन हैं, अभी भी उतना ही एक मास्टर है, क्योंकि जब दास ऑनलाइन वापस आते हैं, तो वे दोहराएंगे कि वे कहाँ छोड़ गए हैं।
एक अर्थ में, या तो सर्वर की ओर से केवल "जागरूकता" यह नहीं है कि क्या यह एक मास्टर है, बल्कि यह है कि क्या यह एक दास है (या "नहीं")।
यही रोलांडो का समाधान पूछता है: "क्या आप गुलाम हैं?" यदि उत्तर नहीं है, तो यह धारणा है कि यह मास्टर होना चाहिए ... जिसे उन्होंने STOP SLAVE;
जारी किए जाने पर एक दोषपूर्ण धारणा के रूप में इंगित किया था। लेकिन एक रुका हुआ गुलाम अभी भी एक गुलाम है, इसलिए "दास नहीं" (किसी भी समय) किसी भी समय "गुरु होने के बराबर" नहीं है।
प्रकल्पित मास्टर पर एक समान परीक्षण किया जा सकता है:
SELECT COUNT(1) FROM information_schema.processlist
WHERE user = 'the_username_used_by_the_slave';
या
SELECT COUNT(1) FROM information_schema.processlist
WHERE command = 'binlog dump';
यदि मान शून्य है, तो दास का IO धागा जुड़ा नहीं है। इस परीक्षण में एक समान दोष है, इसमें अगर गुलाम को प्रशासनिक रूप से अलग कर दिया जाता है, अलग कर दिया जाता है, या असफल हो जाता है, तो यह जुड़ा नहीं होगा। तो यह वास्तव में कुछ भी हल नहीं करता है।
इससे भी बदतर (इन परिदृश्यों में से किसी के लिए) info_schema.processlist "तालिका" एक आभासी तालिका है जो हर बार चुने जाने से पहले भौतिक हो जाती है, और इसमें समय लगता है और संसाधनों का खर्च होता है। आपका सर्वर जितना अधिक व्यस्त होगा, उसकी कीमत उतनी ही अधिक होगी, क्योंकि प्रत्येक थ्रेड की गतिविधि को पेर्ड-इन करना होगा।
एक अधिक हल्का समाधान होगा:
SELECT @@global.read_only;
एक दास पर, आपको वैश्विक चर सेट करना चाहिए / चाहिए read_only
ताकि SUPER
विशेषाधिकार के बिना उपयोगकर्ता अनायास ही इसे नहीं लिख सकें (और आपके आवेदन में नहीं होना चाहिए SUPER
)। यदि आप गुलाम को मास्टर भूमिका में "बढ़ावा" देते हैं, तो आप SET GLOBAL read_only = OFF
लेखन को सक्षम कर सकते हैं। (प्रतिकृति हमेशा दास को लिख सकती है, चाहे वह कैसे भी सेट हो)।
लेकिन यह अभी भी, मुझे लगता है, एक महत्वपूर्ण बिंदु याद आती है:
मैं यह प्रस्ताव करूंगा कि आवेदन इस निर्णय को एक मास्टर / दास सेटअप में न्यायिक रूप से नहीं होना चाहिए, और निश्चित रूप से कनेक्शन-बाय-कनेक्शन के आधार पर नहीं होना चाहिए। एप्लिकेशन को या तो एक हार्ड कॉन्फ़िगरेशन विकल्प का उपयोग करना चाहिए, या एप्लिकेशन को अनजान रहना चाहिए और डेटाबेस कनेक्शन गंतव्य को किसी अन्य चीज़ से नियंत्रित करना चाहिए।
या, कम से कम, अनुप्रयोग को तब तक कभी भी स्विच नहीं करना चाहिए जब तक कि मास्टर विफल न हो जाए, और फिर इसे कभी भी अपने आप वापस स्विच नहीं करना चाहिए।
यहाँ मैं ऐसा क्यों कहता हूँ: एक बार "निर्णय" किया जाता है - जो कोई भी या जो भी - किसी अन्य सर्वर को मास्टर बनाने के लिए, आवेदन को किसी भी कारण से मूल स्वामी के पास वापस जाने की अनुमति नहीं दी जा सकती है, भले ही वह ऑनलाइन वापस आ जाए , हस्तक्षेप के बिना।
मान लें कि आपने बग मारा और एक सॉफ़्टवेयर-मजबूर क्रैश है; mysqld_safe
Dutifully पुनरारंभ होता है mysqld
, और InnoDB क्रैश पुनर्प्राप्ति निर्दोष रूप से करता है। लेकिन इसमें कुछ मिनट लगते हैं।
इस बीच, मास्टर नीचे है इसलिए आपके आवेदन ने दास को बदल दिया है। लेनदेन बनाए गए हैं, ऑर्डर दिए गए हैं, फंड ट्रांसफर किए गए हैं, पोस्ट किए गए कमेंट हैं, ब्लॉग्स संपादित हैं, जो भी आपका सिस्टम करता है।
अब, मूल मास्टर ऑनलाइन वापस आता है।
यदि आपका आवेदन मूल स्वामी के पास वापस चला जाता है, तो आप चोट की एक निरपेक्ष दुनिया में हैं, क्योंकि बहुत ही अगली बात जो होने की संभावना है, वह असंगतता के कारण प्रतिकृति बंद हो जाती है, क्योंकि आपके आवेदन ने दास पर डेटा को बदल दिया है समय। अब आपके पास असंगत डेटा वाले दो डेटाबेस सर्वर हैं जिन्हें आपको मैन्युअल रूप से समेटना होगा। अगर वहाँ डॉलर या अंक या क्रेडिट शामिल हैं, तो आप अब बेमेल शेष हैं।
इसलिए यह महत्वपूर्ण है कि एप्लिकेशन को आपके हस्तक्षेप के बिना मूल मास्टर पर वापस जाने की अनुमति नहीं है।
रुको, क्या आपको इस परिदृश्य के साथ समस्या का पता चला जैसा कि मैंने इसे वर्णित किया है? मास्टर विफल हो गया है, लेकिन आपका एप्लिकेशन दास का उपयोग नहीं करेगा, क्योंकि यह सोचता है कि दास अभी भी गुलाम है और मास्टर नहीं है ... information_schema.processlist
दास पर क्वेरी अभी भी गैर-शून्य वापस आ जाएगी, भले ही मास्टर सर्वर संचालित हो। ।
इसलिए आवेदन की कोई बात नहीं है, कुछ भी पता चलता है, क्योंकि आपको STOP SLAVE
उस परीक्षण के लिए मैन्युअल रूप से उपयोगी होना होगा।
यदि आप चाहते हैं कि स्विच करने में सक्षम होने वाला एक बेहतर तरीका है, तो सर्कुलर प्रतिकृति के साथ सर्वर को कॉन्फ़िगर करना होगा।
परिपत्र प्रतिकृति की स्वयं की अंतर्निहित समस्याएं हैं, लेकिन जब तक आपका आवेदन केवल एक समय में एक सर्वर पर हमेशा लिख रहा होता है, तब तक अधिकांश मुद्दे गैर-मुद्दे बन जाते हैं। दूसरे शब्दों में, दोनों मशीनें हमेशा एक साथ और मास्टर और गुलाम दोनों हैं, एक प्रतिकृति अर्थ में, लेकिन आपका आवेदन, कुछ तंत्र के माध्यम से, हमेशा केवल एक मशीन को "मास्टर" के रूप में इंगित कर रहा है, जिसे वह लिख सकता है और लिखना चाहिए ।
आप उनके अलग होने के कारण MySQL सर्वर पर HA टूल को तैनात नहीं कर सकते हैं, लेकिन आप इसे एप्लिकेशन सर्वर (ओं) पर चलने वाले HAProxy के साथ कार्यान्वित कर सकते हैं। एप्लिकेशन लोकलहोस्ट पर "MySQL" से कनेक्ट होता है, जो MySQL बिल्कुल नहीं है, लेकिन वास्तव में HAProxy है ... और यह उचित MySQL मशीन के लिए TCP कनेक्शन को आगे बढ़ाता है।
HAProxy MySQL सर्वर से कनेक्शन का परीक्षण कर सकता है और केवल MySQL मशीन को ट्रैफ़िक प्रदान करता है जो कनेक्शन स्वीकार कर रहा है और प्रमाणीकरण की अनुमति देता है।
एप्लिकेशन सर्वर पर चल रहे HAProxy के संयोजन (संसाधनों की मांग इसकी सभी चीजों की तुलना में पर्याप्त नहीं होगी, जो एप्लिकेशन सर्वर को करना है - यह बहुत ही बस एक साथ सॉकेट बांधने और उनके पेलोड को अनदेखा करने के लिए है ...) और MySQL परिपत्र प्रतिकृति प्रश्न से ज्ञात क्या है, इसके आधार पर मैं संभवतः इस उदाहरण को देखूंगा।
या, एक सख्ती से मैनुअल सेटअप के लिए, "खोज," की तुलना में कुछ अधिक सरल के साथ जाएं, जैसे /etc/hosts
कि एक होस्टनाम के साथ ऐप सर्वर की फाइल में एक प्रविष्टि जो एप्लिकेशन MySQL से कनेक्ट करने के लिए उपयोग करता है, जिसे आप मैन्युअल रूप से अपडेट कर सकते हैं - गुलाम का प्रचार मास्टर एक मैनुअल प्रक्रिया होने का इरादा है।
या, कुछ अधिक जटिल, पेरकोना XtraDB क्लस्टर का उपयोग कर। हालांकि, इसके लिए आप एक तीसरा सर्वर जोड़ना चाहेंगे, क्योंकि पीएक्ससी में 3 नोड्स के साथ, यदि 2 सर्वर एक दूसरे को देख सकते हैं, लेकिन 1 सर्वर से अलग हो जाते हैं (यदि तीनों अभी भी चल रहे हैं) तो 2 सर्वर खुशी से चलते रहते हैं लेकिन 1 सर्वर एक छोटी गेंद में कर्ल करता है और कुछ भी करने से इनकार करता है क्योंकि यह महसूस करता है कि यह अजीब होना चाहिए। यह काम करता है क्योंकि 2 को एहसास होता है कि वे अभी भी नोड्स के बहुमत का गठन करते हैं जो नेटवर्क विभाजन से पहले ऑनलाइन थे और 1 को पता चलता है कि यह नहीं है। पीएक्ससी के साथ, यह वास्तव में कोई फर्क नहीं पड़ता कि आपका एप्लिकेशन किस सर्वर से कनेक्ट होता है।
मैं कहता हूं कि यह सब कहना है "एप्लिकेशन को सर्वर को पोल करने के लिए नहीं है जो यह देखने के लिए कि कौन सा मास्टर है" क्योंकि यह आपको जल्द या बाद में काटेगा और यह आपके प्रदर्शन को दूर कर देगा जब तक यह दिन काटता है।