2012-10-19 15 views
8

मेरे पास MySQL डेटाबेस है जो लगभग 17   आकार में GB है और इसमें 38 मिलियन प्रविष्टियां हैं। फिलहाल, मुझे दोनों को एक कॉलम के आकार में वृद्धि करने की आवश्यकता है (वर्चर 40 से वर्चर 80) और अधिक कॉलम जोड़ें।मैं लाखों प्रविष्टियों वाले तालिका पर एक MySQL तालिका संरचना को कुशलता से कैसे बदलूं?

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

इस आकार में कुछ बदलाव करने का सबसे प्रभावी तरीका क्या है?

इनमें से कई प्रविष्टियां भी पुरानी हैं और अगर प्रविष्टियों को बंद करने का कोई अच्छा तरीका है लेकिन फिर भी उन्हें उपलब्ध है जो तालिका को अधिक प्रबंधनीय आकार बनाकर इस समस्या में मदद कर सकते हैं।

+0

दिलचस्प। मैं इस सवाल का पालन करता हूं। – Gianmarco

उत्तर

2

MySQL 5.1 के साथ और फिर 5.5 के साथ कुछ निश्चित विवरणों को केवल पूरी तालिका को पुनर्लेखन किए बिना संरचना को संशोधित करने के लिए बढ़ाया गया था (http://dev.mysql.com/doc/refman/5.5/en/alter-table.html - जगह के लिए खोजें)। इसकी उपलब्धता हालांकि आपके द्वारा किए जा रहे परिवर्तन के प्रकार और इंजन में उपयोग के अनुसार बदलती है, सबसे अधिक मूल्य InnoDB प्लगइन से आता है। आपके विशिष्ट परिवर्तनों के मामले में हालांकि पूरी तालिका को फिर से लिखा जाएगा।

जब हमें इन मुद्दों का सामना करना पड़ता है, तो हम आम तौर पर प्रतिकृति डेटाबेस का लाभ उठाने का प्रयास करते हैं। जब तक आप जोड़ रहे हैं और हटा नहीं रहे हैं, तो आप पहले अपनी प्रतिकृति के खिलाफ अपना डीडीएल चला सकते हैं और फिर प्रतिकृति को मास्टर भूमिका में बढ़ावा देने के लिए एक संक्षिप्त आउटेज निर्धारित कर सकते हैं। यदि आप आरडीएस पर होते हैं तो यह उनके प्रतिकृति उदाहरण http://aws.amazon.com/about-aws/whats-new/2012/10/11/amazon-rds-mysql-rr-promotion/ के लिए उनके सुझाए गए उपयोगों में से एक है।

कुछ अन्य विकल्पों में शामिल हैं:

  • वांछित संरचना (उपयोग INTO OUTFILE एक मेज ताला से बचने के लिए) के साथ एक नई तालिका में रिकॉर्ड के सबसेट बाहर का चयन करना। एक बार पूरा होने पर आप एक रखरखाव विंडो और REPLACE INTO या UPDATE प्रारंभिक डेटा प्रति के बाद मूल तालिका में परिवर्तित किए गए किसी भी रिकॉर्ड को शेड्यूल कर सकते हैं। एक बार अपडेट पूरा हो जाने के बाद दोनों टेबलों के RENAME TABLE... परिवर्तनों को लपेट लेते हैं।
  • पेर्कोन के पीटी-ऑनलाइन-स्कीमा-परिवर्तन जैसे टूल का उपयोग करना: http://www.percona.com/doc/percona-toolkit/2.1/pt-online-schema-change.html। यह टूल ट्रिगर्स के साथ काम करता है, इसलिए यदि आपके पास पहले से ही उन टेबल पर ट्रिगर्स हैं जिन्हें आप बदलना चाहते हैं, तो यह आपकी आवश्यकताओं के अनुरूप नहीं हो सकता है।
3

नई संरचना के साथ एक नई तालिका बनाएं जो आप एक अलग नाम के साथ चाहते हैं उदाहरण के लिए न्यूटेबल।

तो निम्न क्वेरी का उपयोग करके पुरानी तालिका से इस नए तालिका में डेटा सम्मिलित करें:

INSERT INTO NewTable (field1, field2, etc...) SELECT field1, field2, ... FROM OldTable 

इस के बाद किया जाता है, तो आप पुराने तालिका ड्रॉप और मूल नाम

को नई तालिका नाम बदल सकते हैं
DROP TABLE `OldTable`; 
RENAME TABLE `NewTable` TO `OldTable` ; 

मैंने इस दृष्टिकोण को एक बहुत बड़ी मेज पर करने की कोशिश की है और यह तालिका को बदलने से कहीं अधिक तेज़ है।

6

आपके पास कुछ विकल्प हैं।

किसी भी मामले में आपको यह सामान करने से पहले बैकअप लेना चाहिए।

एक संभावना आपकी सेवा को ऑफ़लाइन लेना और इसे करने के लिए, जैसा आपने कोशिश की है, इसे करने के लिए है। यदि आप ऐसा करते हैं तो आपको कुंजी जांच और बाधाओं को अक्षम करना चाहिए।

ALTER TABLE bigtable DISABLE KEYS; 
SET FOREIGN_KEY_CHECKS=0; 
ALTER TABLE (whatever); 
ALTER TABLE (whatever else); 
... 
SET FOREIGN_KEY_CHECKS=1; 
ALTER TABLE bigtable ENABLE KEYS; 

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

एक और संभावना नई स्कीमा के साथ एक नई तालिका बनाने के लिए है, फिर नई तालिका पर चाबियाँ अक्षम करें, फिर @Bader सुझाएं और पुरानी तालिका की सामग्री डालें।

अपनी नई तालिका बनने के बाद आप उस पर कुंजी को फिर से सक्षम कर देंगे, फिर पुरानी तालिका का नाम "old_bigtable" जैसे नाम पर पुनर्नामित करें, फिर नई तालिका को "bigtable" में बदलें।

यह संभव है कि आप नई तालिका को पॉप्युलेट करते समय अपनी सेवा ऑनलाइन रख सकें। लेकिन यह खराब काम कर सकता है।

एक तीसरी संभावना अपनी विशाल तालिका (एक फ्लैट फ़ाइल में) डंप करना है और फिर इसे नए लेआउट के साथ एक नई तालिका में लोड करना है। यह दूसरी संभावना की तरह काफी है, सिवाय इसके कि आपको एक टेबल बैकअप मुफ्त में मिलता है। आप इसे SELECT DATA INTO OUTFILE और LOAD DATA INFILE के साथ बहुत तेज बना सकते हैं। ऐसा करने के लिए आपको अपने सर्वर मशीन की फ़ाइल सिस्टम तक पहुंच की आवश्यकता होगी।

सभी मामलों में, चीजों को तेजी से जाने के लिए बाधाओं और चाबियों को अक्षम, फिर से सक्षम करें।

+1

पहला ऐसा लगता है जो मैं चाहता हूं मुझे लगता है कि मैं अमेज़ॅन आरडीएस उदाहरण के कुछ घंटे पहले कताई करने का प्रयास करूंगा और किसी अन्य आउटेज की कोशिश करने से पहले इसे कोशिश करूँगा। – marioatlp

+2

सप्ताहांत में इस पर काम करने के लिए समय होने के बाद इस विधि के साथ समस्या यह है कि innodb आपको चाबियाँ अक्षम करने नहीं देता है। – marioatlp

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