Mysql मास्टर-गुलाम में मास्टर का निर्धारण कैसे करें


17

मैं MySQL मास्टर-दास प्रतिकृति स्थापित कर रहा हूं और मैं यह पता लगाने की कोशिश कर रहा हूं कि मैं फेलओवर की स्थिति को कैसे संभाल सकता हूं जहां मैं दास को मास्टर को बढ़ावा देता हूं (इस घटना में कि मास्टर नीचे जाता है)।

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

मुझे लगता है कि यह कुछ ऐसा है जिसे मुझे एप्लिकेशन स्तर पर संभालने की आवश्यकता है। मैं दो सर्वरों को क्वेरी कर सकता हूं और पूछ सकता हूं कि कौन सा एक मास्टर है, फिर उस पर सभी प्रश्न करें।

क्या MySQL में यह देखने के लिए कोई क्वेरी है कि क्या वर्तमान सर्वर मास्टर-स्लेव प्रतिकृति में मास्टर है?


MySQL के किस संस्करण का आप उपयोग कर रहे हैं ???
RolandoMySQLDBA

यह mysql आउटपुट हैServer version: 5.5.23 MySQL Community Server (GPL)
एथन ह्योन

जवाबों:


13

@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_safeDutifully पुनरारंभ होता है 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 को पता चलता है कि यह नहीं है। पीएक्ससी के साथ, यह वास्तव में कोई फर्क नहीं पड़ता कि आपका एप्लिकेशन किस सर्वर से कनेक्ट होता है।

मैं कहता हूं कि यह सब कहना है "एप्लिकेशन को सर्वर को पोल करने के लिए नहीं है जो यह देखने के लिए कि कौन सा मास्टर है" क्योंकि यह आपको जल्द या बाद में काटेगा और यह आपके प्रदर्शन को दूर कर देगा जब तक यह दिन काटता है।


सबसे पहले, अच्छी तरह से लिखित प्रतिक्रिया के लिए धन्यवाद। मुझे लगता है कि आपने एक अच्छा समाधान प्रस्तावित किया है। मैंने अतीत में परिपत्र प्रतिकृति का उपयोग करने के बारे में सोचा है, लेकिन इसकी विश्वसनीयता के बारे में बुरी बातें पढ़ी हैं। हालाँकि, इनमें से अधिकांश समस्याओं को auto_increment_increment, auto_increment_offset, आदि को संशोधित करके रोका जा सकता है ... अनुप्रयोग सर्वरों पर स्थानीय रूप से HAProxy का उपयोग करना (केवल विफलता के रूप में) हमारे लिए अच्छा काम करेगा क्योंकि हमें अपने आवेदन को संशोधित नहीं करना होगा, इसलिए विफलता को अमूर्त करना आवेदन परत से दूर तर्क। मैं HAProxy को कॉन्फ़िगर करने पर ध्यान दूंगा, धन्यवाद!
एथन ह्योन

1
मदद करने में खुशी। यदि आप पहले से ही नहीं हैं तो एक अप-वोट की सराहना की जाएगी। जब तक आप समझते हैं कि यह कैसे काम करता है और इसे समझदार तरीके से उपयोग करता है, तो परिपत्र प्रतिकृति मास्टर / दास (यह एक ही तकनीक, बस दोनों दिशाओं में जा रही है) के रूप में विश्वसनीय है। जब तक सर्वर ठीक से सिंक हो जाते हैं और एप्लिकेशन एक समय में केवल एक सर्वर पर लिख रहा होता है, तब तक मुझे इससे कोई समस्या नहीं होती है। auto_increment_*चर अभी भी "बस मामले में।" इस परिदृश्य में उपयोग करने के लिए अच्छे हैं, इसके अलावा, उपयोग करना याद रखें binlog_format= rowया mixedनहीं statement(भले ही आप परिपत्र नहीं कर रहे हों)।
माइकल -

मैंने स्वीकार किए गए उत्तर को पूरी तरह से बदल दिया क्योंकि इस विस्तृत विवरण ने मुझे सिस्टम को और अधिक मजबूत बनाने में मदद की। @ RolandoMySQLDBA का उत्तर अभी भी सही है और मेरे द्वारा बताई गई समस्या को हल करता है। धन्यवाद!
एथन ह्योन

10

यदि आप केवल मास्टर / दास का उपयोग कर रहे हैं, तो यहां कुछ त्वरित और गंदा है:

SELECT COUNT(1) SlaveThreadCount
FROM information_schema.processlist
WHERE user='system user';

यह आपको क्या कहता है?

  • यदि SlaveThreadCount= 0, आपके पास मास्टर है
  • अगर SlaveThreadCount> 0, आपके पास दास है

गुफा : यह तब तक काम करता है जब तक आप दौड़ते नहीं हैंSTOP SLAVE;

कोशिश करने के लिए एक और बात यह है: यदि आप दास पर बाइनरी लॉगिंग को अक्षम करते हैं और आप चलाते हैं SHOW MASTER STATUS;, तो मास्टर आपको वर्तमान बाइनरी लॉग देता है। दास आपको कुछ नहीं देता है।


बहुत बढ़िया, यह वही है जो मुझे चाहिए। क्या आपको लगता है कि यह समस्या का एक गन्दा समाधान है? केवल एक ही मुद्दा मैं कल्पना कर सकता हूं कि दोनों सर्वरों को मास्टर के रूप में प्रचारित किया जा रहा है, लेकिन वास्तव में ऐसा कभी नहीं होना चाहिए।
एथन ह्योन

यदि यह उत्तर आपके लिए आवश्यक है, तो कृपया मेरे उत्तर पर चेकमार्क पर क्लिक करके स्वीकृत उत्तर को चिह्नित करें।
RolandoMySQLDBA

मैं इसे 5 मिनट के लिए स्वीकार नहीं कर सकता हूं :)
एथन ह्योन

कोई दिक्कत नहीं है। मुझे खुशी थी कि मैं मदद कर सकता था !!!
RolandoMySQLDBA

0

mysql प्रॉम्प्ट
mysql> शो स्लेव स्टेटस से इस स्टेटमेंट को निष्पादित करें ;

दास पर यह बहुत सारे मापदंडों और उनके मूल्यों / स्थिति को दर्शाता है जबकि मास्टर पर यह खाली सेट दिखाता है

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