InnoDB

2009-03-17 17 views
28

के वैकल्पिक तालिका के लिए MySQL को अनुकूलित करना जल्द ही हमें अपने उत्पादन डेटाबेस में स्कीमा परिवर्तन करने की आवश्यकता होगी। हमें इस प्रयास के लिए डाउनटाइम को कम करने की आवश्यकता है, हालांकि, अल्टर टेबल स्टेटमेंट थोड़ी देर के लिए चलने जा रहे हैं। हमारी सबसे बड़ी टेबल में 150 मिलियन रिकॉर्ड हैं, सबसे बड़ी टेबल फ़ाइल 50 जी है। सभी टेबल InnoDB हैं, और इसे एक बड़ी डेटा फ़ाइल (फ़ाइल-प्रति-तालिका के बजाय) के रूप में स्थापित किया गया था। हम 8 कोर मशीन, 16 जी मेमोरी और RAID10 कॉन्फ़िगरेशन पर MySQL 5.0.46 चला रहे हैं।InnoDB

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

स्कीमा परिवर्तन जो हम करने की योजना बना रहे हैं वह सभी तालिकाओं में एक पूर्णांक कॉलम जोड़ रहा है और वर्तमान प्राथमिक कुंजी के बजाय इसे प्राथमिक कुंजी बना रहा है। हमें 'पुराने' कॉलम को भी रखने की आवश्यकता है ताकि मौजूदा मानों को ओवरराइट करना एक विकल्प न हो।

इस कार्य को यथासंभव शीघ्रता से प्राप्त करने के लिए आदर्श सेटिंग्स क्या होगी?

+0

संबंधित: http://stackoverflow.com/q/9524938/632951 – Pacerier

उत्तर

-4

मुझे वास्तव में यह नहीं पता कि इसे कैसे अनुकूलित किया जाए, लेकिन आमतौर पर इस तरह के अपडेट करने से पहले साइट को ऑफलाइन मोड में रखना एक अच्छा अभ्यास है।

फिर, आप अपनी डीबी स्क्रिप्ट को 3 बजे कह सकते हैं, इसलिए यदि डाउनटाइम आदर्श से बड़ा लंबा हो तो इससे कोई फर्क नहीं पड़ता।

+0

हां - हम इस कार्य को करने के लिए रात के घंटों के दौरान साइट को नीचे लाएंगे। लेकिन ऐसी बड़ी तालिकाओं के साथ अल्टर टेबल कई घंटों तक चल सकता है, और शायद यह एक रात में फिट नहीं होगा :( – schuilr

+0

हो सकता है कि आप उत्पादन डीबी समय के डंप के साथ एक अलग सर्वर में स्क्रिप्ट को चलाने के लिए चाहते हैं उम्मीद है कि आपको बहुत अच्छा लगेगा! :) – Seb

+0

हां, हम इसके लिए एक क्यूए पर्यावरण तैयार कर रहे हैं। अपने अनुकूलन का परीक्षण किए बिना अनुकूलित नहीं कर सकते;) – schuilr

15

आपको अपनी आवश्यकताओं के बारे में थोड़ा और सावधानी से सोचने की आवश्यकता है।

सबसे सरल स्तर पर, तालिका को बदलने के लिए "सबसे तेज़" तरीका यह है कि इसे संभवतः ALTER TABLE कथन जितना संभव हो उतना करना है, अधिमानतः एक। ऐसा इसलिए है क्योंकि MySQL स्कीमा को बदलने और पंद्रह परिवर्तन करने के लिए तालिका के डेटा की प्रतिलिपि बनाता है, जबकि एक प्रतिलिपि बनाने के लिए पंद्रह बार तालिका को कॉपी करने से पहले (और वास्तव में) तेज है, एक समय में एक बदलाव कर रहा है।

लेकिन मुझे संदेह है कि आप कम से कम डाउनटाइम के साथ इस परिवर्तन को कैसे करें। जिस तरह से मैं ऐसा करता हूं, आप मूल रूप से गैर-ब्लॉक ALTER TABLE काम करने के तरीके को संश्लेषित करते हैं। लेकिन यह कुछ अतिरिक्त आवश्यकताओं है:

  1. आप इस तरह के बाद के लिए एक "संशोधित" दिनांक फ़ील्ड, या पूर्व के लिए एक AUTO_INCREMENT क्षेत्र के साथ के रूप में जोड़ा गया है और बदल डेटा, ट्रैक करने के लिए एक तरह से की जरूरत है।
  2. आपको डेटाबेस पर अपनी तालिका की दो प्रतियां रखने के लिए स्थान की आवश्यकता है।
  3. आप एक समय अवधि जहां मेज पर परिवर्तन बहुत दूर एक स्नैपशॉट

से आगे बुनियादी तकनीक आप का सुझाव दिया है, यानी एक INSERT INTO ... SELECT ... का उपयोग कर के रूप में है नहीं मिलेगा की जरूरत है। कम से कम आप सामने हैं क्योंकि आप एक InnoDB तालिका से शुरू कर रहे हैं, इसलिए SELECT अवरुद्ध नहीं होगा। मैं नई, खाली तालिका पर ALTER TABLE करने की अनुशंसा करता हूं, जो MySQL को फिर से सभी डेटा कॉपी करने से बचाएगा, जिसका अर्थ यह होगा कि आपको INSERT INTO ... SELECT ... कथन में सभी फ़ील्ड को सही ढंग से सूचीबद्ध करने की आवश्यकता है। फिर आप इसे स्वैप करने के लिए एक सरल RENAME कथन कर सकते हैं। फिर आपको सभी संशोधित डेटा को पकड़ने के लिए INSERT INTO ... SELECT ... WHERE ... और शायद UPDATE ... INNER JOIN ... WHERE ... करने की आवश्यकता है।आपको INSERT और UPDATEजल्दी या अपने कोड को अपने स्नैपशॉट में नई पंक्तियां और अपडेट जोड़ने शुरू कर देंगे जो आपके अपडेट में हस्तक्षेप करेगा। (यदि आप RENAME से कुछ मिनट पहले अपने ऐप को रखरखाव मोड में डाल सकते हैं तो आपको यह समस्या नहीं होगी।)

इसके अलावा, कुछ प्रमुख और बफर संबंधित सेटिंग्स हैं जिन्हें आप केवल एक के लिए बदल सकते हैं सत्र जो मुख्य डेटा चाल में मदद कर सकता है। read_rnd_buffer_size और read_buffer_size जैसी चीजें बढ़ाने के लिए उपयोगी होंगी।

11

दुर्भाग्यवश, यह staticsan जितना आसान नहीं है, उसके उत्तर में आगे बढ़ता है। ऑनलाइन होने पर और डेटा को स्थानांतरित करने के दौरान नई तालिका बनाना काफी आसान है, और रखरखाव मोड में सफाई के दौरान सफाई करना भी पर्याप्त सक्षम है, हालांकि, MySQL RENAME ऑपरेशन स्वचालित रूप से आपकी पुरानी तालिका में किसी भी विदेशी कुंजी संदर्भों का उपयोग करता है। इसका अर्थ यह है कि मूल तालिका के लिए कोई भी विदेशी कुंजी संदर्भ तब भी इंगित करेगा जो आप तालिका का नाम बदलते हैं।

तो, यदि आपके पास तालिका के लिए कोई विदेशी कुंजी संदर्भ है तो आप बदलने की कोशिश कर रहे हैं या तो आप अपनी नई तालिका के संदर्भ को बदलने के लिए उन तालिकाओं को बदल रहे हैं, या इससे भी बदतर है कि यदि तालिका बड़ी है तो आपको दोहराना होगा बड़ी तालिका संख्या दो के साथ प्रक्रिया।

अतीत में हमारे लिए काम करने वाला एक अन्य दृष्टिकोण माइस्क्ल प्रतिकृतियों को बदलने के लिए एक सेट को जोड़ना है। मैं प्रक्रिया से बात करने के लिए सबसे अच्छा व्यक्ति नहीं हूं, लेकिन मूल रूप से एक दास को तोड़ने की प्रतिकृति होती है, उस उदाहरण पर पैच चलाते हुए, परिवर्तन तालिका पूरी होने के बाद प्रतिकृति को वापस कर दिया जाता है ताकि यह प्रतिकृति पर पकड़ सके। एक बार प्रतिकृति पकड़ने के बाद, आप अपने मास्टर से इस नए पैच वाले दास को नए मास्टर डेटाबेस के रूप में स्विच करने के लिए साइट को रखरखाव मोड (यदि आवश्यक हो) में डाल दें।

केवल एक चीज जिसे मैं याद नहीं कर सकता वह ठीक है जब आप नए गुरु पर अन्य दासों को इंगित करते हैं ताकि वे भी लागू हो जाएं। इस प्रक्रिया के लिए एक चेतावनी, कोड को बदलने की आवश्यकता होने से पहले कोड को बदलने के बाद, या कॉलम/चाबियों का संदर्भ देने के बाद हम आम तौर पर इसे पैच बदलने के लिए उपयोग करते हैं।

+0

मैंने विदेशी कुंजी के बारे में सोचा नहीं था। जहां मैं एक डीबीए था जहां मैंने वर्णित तकनीक का उपयोग किया था, हमने विदेशी कुंजी का उपयोग बिल्कुल नहीं किया क्योंकि आवेदन पर विश्वास था और केवल यह सब कुछ संभाला था। – staticsan

12
  1. सेटअप गुलाम
  2. बंद करो प्रतिकृति।
  3. गुलाम
  4. पर ALTER बनाओ गुलाम मास्टर
  5. स्वैप स्वामी और गुलाम पकड़ने दें, ताकि गुलाम बदली हुई संरचना और न्यूनतम डाउनटाइम के साथ उत्पादन सर्वर हो जाता है
15

आप Percona से pt-online-schema-change को देखने के लिए चाहते हो सकता है टूलकिट। अनिवार्य रूप से यह क्या करता है:

  • मूल तालिका संरचना की प्रतिलिपि बनाता है, ALTER।
  • पुरानी तालिका से नई बनाई गई पंक्तियों की पंक्तियां कॉपी करता है।
  • कॉपी करते समय परिवर्तनों को ट्रैक और सिंक करने के लिए ट्रिगर्स का उपयोग करता है।
  • जब सब कुछ खत्म हो जाता है तो यह दोनों नामकरण करके टेबल को स्वैप करता है।

एकल उदाहरण डेटाबेस के लिए बहुत अच्छी तरह से काम करता है, लेकिन यदि आप प्रतिकृति का उपयोग करते हैं तो आप काफी मुश्किल हो सकते हैं और आप दासों को रोकने और बाद में पुनर्निर्माण नहीं कर सकते हैं।

इस here के बारे में भी एक अच्छा वेबिनार है।

पीएस: मुझे पता है कि यह एक पुराना सवाल है, अगर कोई इसे खोज इंजन के माध्यम से हिट करता है तो जवाब दे रहा है।

+1

पीटी-ऑनलाइन-स्कीमा-परिवर्तन दस्तावेज़ों से एक नोट: ट्रिगर्स का उपयोग यह है कि यदि कोई ट्रिगर पहले से ही तालिका पर परिभाषित किया गया है तो टूल काम नहीं करेगा। – cgaldiolo

5

मैंने एक बदलाव तालिका को तेज करने के लिए विभिन्न रणनीतियों का परीक्षण किया। आखिरकार मुझे अपने विशेष मामले में लगभग 10x की गति में वृद्धि हुई। परिणाम आपकी स्थिति पर लागू हो सकते हैं या नहीं भी हो सकते हैं। हालांकि, इस पर आधारित मैं इनो डीबी लॉग फ़ाइल/बफर आकार पैरामीटर के साथ प्रयोग करने का सुझाव दूंगा।

छोटा है, केवल बढ़ रही innodb_log_file_size और innodb_log_buffer_size में एक औसत दर्जे का प्रभाव (सावधान! innodb_log_file_size बदलने जोखिम भरा है। अधिक जानकारी के लिए नीचे दिए गए देखो) था।

किसी न किसी लिखने की डेटा दर (iostat) और cpu गतिविधि के आधार पर बाधा आईओ आधारित थी, लेकिन डेटा थ्रूपुट नहीं थी। 500 के दशक में लिखने के माध्यम से लिखने के माध्यम से कम से कम उसी बॉलपार्क में होता है जिसे आप हार्ड डिस्क से अपेक्षा करते हैं।

की कोशिश की प्रदर्शन अनुकूलन:

पर "लॉगिंग सुझावों" देखो बदलने innodb_log_file_size खतरनाक हो सकता है।http://www.mysqlperformanceblog.com/2011/07/09/how-to-change-innodb_log_file_size-safely/ देखें लिंक में वर्णित तकनीक (फ़ाइल चाल) मेरे मामले में अच्छी तरह से काम किया।

innodb और ट्यूनिंग लॉग आकारों के बारे में जानकारी के लिए http://www.mysqlperformanceblog.com/2007/11/03/choosing-innodb_buffer_pool_size/ और http://www.mysqlperformanceblog.com/2008/11/21/how-to-calculate-a-good-innodb-log-file-size/ भी देखें। बड़ी लॉग फ़ाइलों का एक दोष दुर्घटना के बाद लंबे समय तक वसूली का समय है।

टेस्ट रन और किसी न किसी समय:

  • एक ताजी createad तालिका करने के लिए सरल लोड डेटा: 6500s
  • लोड डेटा डब्ल्यू। innodb_log_file_size = 200M, innodb_log_buffer_size = 8M, innodb_buffer_pool_size = 2200M, autocommit = 0; unique_checks = 0, foreign_key_checks = 0: 500s
  • लोड डेटा डब्ल्यू। innodb_log_file_size = 200M, innodb_log_buffer_size = 8M: 500s
  • समतुल्य सीधे तालिका w।datainnodb_log_file_size = 200M, innodb_log_buffer_size = 8M: 500s

परीक्षण विवरण: तालिका: InnoDB, 6M पंक्तियाँ, डिस्क, एकल फाइल (innodb_file_per_table विकल्प) पर 2.8g, प्राथमिक कुंजी 1 पूर्णांक, 2 की कमी unque है/सूचकांक, 8 कॉलम, औसत। पंक्ति लंबाई 218 बाइट्स। सर्वर: उबंटू 12.04, x86_64, वर्चुअल मशीन, 8 कोर, 16 जीबी, सटा उपभोक्ता ग्रेड डिस्क, कोई RAID नहीं, कोई डेटाबेस गतिविधि नहीं, अन्य प्रक्रिया गतिविधि को कम करें, अन्य और बहुत छोटी आभासी मशीनों में कमजोर गतिविधि। MySQL 5.1.53। 1400 एम के innodb_buffer_pool_size के अलावा प्रारंभिक सर्वर कॉन्फ़िगरेशन बहुत डिफ़ॉल्ट है। परिवर्तन तालिका 2 छोटे कॉलम जोड़ती है। मैंने कच्ची परिवर्तन तालिका नहीं देखी, लेकिन इसके बजाय बराबर लोड डेटा इन्फाइल स्टेटमेंट के साथ प्रयोग किया, आखिरकार मैंने सीधे बदलाव किया और तुलनात्मक परिणाम मिला।

यह सवाल कम से कम निम्न प्रश्नों से संबंधित है:

+0

शानदार जवाब, यह कई और वोटों के हकदार है। अपने शोध और परिणामों को प्रकाशित करने के लिए धन्यवाद। – culix

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