क्या आप GTID मोड में MySQL स्टार्टअप समय को धीमा अनुभव कर रहे हैं? हमने हाल ही में अपने एक MySQL होस्टिंग परिनियोजन पर इस समस्या का सामना किया और समस्या को हल करने के लिए निकल पड़े। इस ब्लॉग में, हम उस मुद्दे को तोड़ते हैं जो आपके MySQL पुनरारंभ समय को धीमा कर सकता है, अपने परिनियोजन के लिए डीबग कैसे करें, और आप अपने प्रारंभ समय को कम करने और जीटीआईडी-आधारित प्रतिकृति की अपनी समझ को बेहतर बनाने के लिए क्या कर सकते हैं।
हमें समस्या कैसे मिली
हम कम अंत, डिस्क-आधारित MySQL 5.7.21 परिनियोजन पर धीमी MySQL स्टार्टअप समय की जांच कर रहे थे जिसमें GTID मोड सक्षम था। सिस्टम एक मास्टर-दास जोड़ी का हिस्सा था और एक मध्यम लेखन भार के अधीन था। शेड्यूल किए गए रखरखाव के दौरान पुनरारंभ करते समय, हमने देखा कि डेटाबेस सर्वर को शुरू होने और कनेक्शन स्वीकार करना शुरू करने में 5-10 मिनट लगे। इस तरह की देरी का कोई मतलब नहीं था, इसलिए हम जांच के लिए निकल पड़े।
आपका धीमा MySQL प्रारंभ समय डीबग करना
हमने लोकप्रिय Percona टूल pt-ioprofile का उपयोग यह देखने के लिए किया कि डेटाबेस क्या कर रहा है। पीटी-आईओप्रोफाइल Percona के लोकप्रिय टूलकिट में एक बहुत ही महत्वपूर्ण उपयोगिता है जिसका उपयोग MySQL समस्याओं को डीबग करने के लिए किया जाता है, और आप उनके दस्तावेज़ीकरण में सुविधाओं की पूरी सूची देख सकते हैं। pt-ioprofile टूल स्ट्रेस . का उपयोग करता है और lsof किसी प्रक्रिया के I/O को देखने और फ़ाइलों की तालिका और I/O गतिविधि का प्रिंट आउट लेने के लिए।
इसलिए, हमने MySQL शुरू किया, mysqld की प्रतीक्षा की उत्पन्न करने के लिए प्रक्रिया, और प्रारंभ किया pt-ioprofile यह देखने के लिए कि समस्या क्या हो सकती है:
# pt-ioprofile --profile-process mysqld --run-time 200 Tue Oct 9 15:42:24 UTC 2018 Tracing process ID 18677 total pread read pwrite write fsync fdatasync open close getdents lseek fcntl filename ... 216.550641 0.000000 216.550565 0.000000 0.000000 0.000000 0.000000 0.000015 0.000040 0.000000 0.000021 0.000000 /mysql_data/binlogs/mysql-bin.000014 ...
आपके MySQL पुनरारंभ को क्या धीमा कर रहा है?
इसे कई बार चलाने पर, हमने निम्नलिखित देखा:
- द mysqld प्रक्रिया अपना अधिकांश समय नवीनतम बाइनरी लॉग फ़ाइल को पढ़ने में बिता रही थी। ऐसा तब भी था जब सर्वर को इनायत से बंद कर दिया गया था और क्रैश रिकवरी आदि की कोई आवश्यकता नहीं थी।
- सर्वर ने InnoDB डेटा फ़ाइलों को लोड करने में भी काफी समय बिताया, लेकिन वह समय नवीनतम बाइनरी लॉग फ़ाइल को पढ़ने में लगने वाले समय की तुलना में बहुत कम था।
- यदि सर्वर को तुरंत फिर से शुरू किया गया था, तो यह बाद का पुनरारंभ बहुत तेज होगा।
- चूंकि डेटाबेस शटडाउन बाइनरी लॉग को फ्लश करता है और स्टार्टअप पर एक नया बनाता है, हमने एक अतिरिक्त प्रयोग किया - सर्वर को बंद करने से पहले, हमने बाइनरी लॉग को फ्लश किया। बाद में सर्वर प्रारंभ फिर से तेज था।
इन टिप्पणियों ने स्पष्ट रूप से इस तथ्य की ओर इशारा किया कि MySQL नवीनतम बाइनरी लॉग फ़ाइल को पढ़ने में बहुत समय व्यतीत कर रहा था। अगर फ़ाइल छोटी थी, जैसे कि जब लॉग फ़ाइल को शटडाउन से पहले फ़्लश किया गया था, तो स्टार्टअप तेज़ था।
GTID में MySQL का प्रारंभ समय धीमा? आपकी बाइनरी लॉग फ़ाइल का आकार समस्या हो सकता हैट्वीट करने के लिए क्लिक करें
बिनलॉग GTID पुनर्प्राप्ति को समझना
जैसा कि यह पता चला है, gtid_executed और gtid_purged के मानों को पॉप्युलेट करने के लिए, MySQL सर्वर को बाइनरी लॉग फ़ाइलों को पार्स करना होगा।
यहां एक FALSE या TRUE रीडिंग के आधार पर MySQL 5.7 प्रलेखन विधि अनुशंसा का सारांश दिया गया है:
जब binlog_gtid_simple_recovery =गलत:
गणना करने के लिए gtid_executed:
- नवीनतम से बाइनरी लॉग फ़ाइलों को पुनरावृत्त करें, पहली फ़ाइल पर रुककर जिसमें पिछला_gtids_log_event है प्रवेश।
- पिछला_gtids_log_event से सभी GTID का उपभोग करें और Gtid_log_events इस बाइनरी लॉग फ़ाइल से, और इस GTID सेट को आंतरिक रूप से संग्रहीत करें। इसे gtids_in_binlog. . कहा जाता है
- gtid_executed का मान gtids_in_binlog . के संघ के रूप में गणना की जाती है और GTIDs mysql.gtid_executed तालिका . में ।
इस प्रक्रिया में बहुत समय लग सकता है यदि GTID के बिना बड़ी संख्या में बाइनरी लॉग फ़ाइलें हैं, उदाहरण के लिए, जब gtid_mode बनाई गई हों =बंद।
इसी तरह, गणना करने के लिए gtid_purged:
- सबसे पुराने से नवीनतम तक बाइनरी लॉग फ़ाइलों को पुनरावृत्त करें, पहले बाइनरी लॉग पर रुककर जिसमें या तो एक गैर-रिक्त पिछला_gtids_log_event शामिल है (कम से कम एक GTID है), या जिसमें कम से कम एक Gtid_log_event है ।
- पढ़ें पिछला_gtids_log_event इस फ़ाइल से। आंतरिक चर की गणना करें gtids_in_binlog_not_purged चूंकि यह GTID सेट gtids_in_binlog. . से घटाया गया है
- gtid_purged . का मान gtid_executed . पर सेट है , घटा gtids_in_binlog_not_purged ।
इसलिए, यह हमारी समझ का आधार बनता है कि पुराने संस्करणों में चीजें कैसे काम करती थीं। हालांकि, कुछ अनुकूलन तब किए जा सकते हैं जब binlog_gtid_simple_recovery सच हैं। यह वह मामला है जिसमें हम रुचि रखते हैं:
कब binlog_gtid_simple_recovery =सच:
(ध्यान दें, यह MySQL 5.7.7 और बाद के संस्करण में डिफ़ॉल्ट है)
- केवल सबसे पुरानी और नवीनतम बाइनरी लॉग फ़ाइलें पढ़ें।
- गणना करें gtid_purged पिछला_gtids_log_event . से या Gtid_log_event सबसे पुरानी बाइनरी लॉग फ़ाइल में मिला।
- गणना gtid_executed पिछला_gtids_log_event . से या Gtid_log_event नवीनतम बाइनरी लॉग फ़ाइल में मिला।
- इस प्रकार, केवल दो बाइनरी लॉग फ़ाइलें सर्वर के पुनरारंभ होने के दौरान या बाइनरी लॉग को शुद्ध करते समय पढ़े जाते हैं।
इसलिए, MySQL संस्करण 5.7.7 और इसके बाद के संस्करण के लिए, नवीनतम और पुरानी बाइनरी लॉग फ़ाइलें हमेशा सिस्टम स्टार्टअप के दौरान GTID सिस्टम वैरिएबल को सही ढंग से प्रारंभ करने के लिए पढ़ी जाती हैं। सबसे पुरानी बाइनरी लॉग फ़ाइल को पढ़ना उतना महंगा नहीं है, क्योंकि MySQL जिस इवेंट की तलाश कर रहा है, वह है, पिछला_gtids_log_event, बाइनरी लॉग फ़ाइल में हमेशा पहला इवेंट होता है।
हालांकि, gtid_executed की सही गणना करने के लिए , सर्वर को संपूर्ण नवीनतम बाइनरी लॉग फ़ाइल को पढ़ना चाहिए और उस फ़ाइल की सभी घटनाओं को एकत्रित करना चाहिए। इसलिए, सिस्टम स्टार्टअप समय नवीनतम बाइनरी लॉग फ़ाइल के आकार के सीधे आनुपातिक हो जाता है ।
ध्यान दें कि binlog_gtid_simple_recovery के समय स्थिति और भी खराब हो जाती है गलत . है . चूंकि यह अब हाल के रिलीज में डिफ़ॉल्ट विकल्प नहीं है, इसलिए यह ज्यादा चिंता का विषय नहीं है।
अपने धीमे प्रारंभ समय का समाधान कैसे करें
जिस समस्या का हम सामना कर रहे थे, उसके कारण को समझने के बाद, हमने जो समाधान तय किया वह काफी स्पष्ट था - बाइनरी लॉग फ़ाइलों का आकार कम करें। बाइनरी लॉग फ़ाइलों का डिफ़ॉल्ट आकार 1GB है। स्टार्टअप के दौरान इस आकार की फ़ाइल को पार्स करने में समय लगता है, इसलिए max_binlog_size के मान को कम करना समझदारी है कम मूल्य पर।
यदि बाइनरी लॉग फ़ाइल के आकार को कम करना कोई विकल्प नहीं है, तो mysqld प्रक्रिया के रखरखाव शटडाउन से ठीक पहले बाइनरी लॉग फ़ाइलों को फ़्लश करने से मदद मिल सकती है बिनलॉग GTID पुनर्प्राप्ति समय को कम करने के लिए।