[२०१ My] अपडेट: MySQL 5.6 में ऑनलाइन इंडेक्स अपडेट के लिए समर्थन है
https://dev.mysql.com/doc/refman/8.0/en/innodb-online-ddl-operations.html#online-ddl-index-syntax-notes
MySQL 5.6 और उच्चतर में, तालिका पढ़ने और लिखने के लिए उपलब्ध रहती है जबकि सूचकांक बनाया या गिराया जा रहा है। CREATE INDEX या DROP INDEX स्टेटमेंट केवल उन सभी लेन-देन के बाद खत्म होता है जो टेबल तक पहुंच रहे हैं, पूरे हो गए हैं, ताकि इंडेक्स की प्रारंभिक स्थिति तालिका की सबसे हाल की सामग्री को दर्शाए। पहले, तालिका को संशोधित करते समय एक इंडेक्स बनाया या गिराया जाता है, जिसके परिणामस्वरूप तालिका में INSERT, UPDATE, या DELETE कथन को रद्द करने वाला गतिरोध उत्पन्न होता है।
[२०१५] अपडेटिंग टेबल इंगित करता है कि ब्लॉक MySQL 5.5 में लिखते हैं
उपरोक्त उत्तर से:
"यदि डेटाबेस के ऑनलाइन होने के दौरान 5.1 से अधिक सूचकांकों का उपयोग करने पर आपका निर्माण होता है। तो चिंता न करें कि आप उत्पादन प्रणाली के उपयोग को बाधित नहीं करेंगे।"
यह **** FALSE **** है (कम से कम MyISAM / InnoDB तालिकाओं के लिए, जो कि वहां के 99.999% लोग उपयोग करते हैं। क्लस्टर संस्करण अलग है।)
एक मेज पर अद्यतन संचालन कर रहा होगा ब्लॉक , जबकि सूचकांक बनाया जा रहा है। MySQL वास्तव में, वास्तव में इस बारे में बेवकूफ है (और कुछ अन्य चीजें)।
टेस्ट स्क्रिप्ट:
(
for n in {1..50}; do
#(time mysql -uroot -e 'select * from website_development.users where id = 41225\G'>/dev/null) 2>&1 | grep real;
(time mysql -uroot -e 'update website_development.users set bio="" where id = 41225\G'>/dev/null) 2>&1 | grep real;
done
) | cat -n &
PID=$!
sleep 0.05
echo "Index Update - START"
mysql -uroot website_development -e 'alter table users add index ddopsonfu (last_name, email, first_name, confirmation_token, current_sign_in_ip);'
echo "Index Update - FINISH"
sleep 0.05
kill $PID
time mysql -uroot website_development -e 'drop index ddopsonfu on users;'
मेरा सर्वर (InnoDB):
Server version: 5.5.25a Source distribution
आउटपुट (नोटिस कैसे 6 वें ऑपरेशन ब्लॉक ~ 400ms के लिए यह सूचकांक अद्यतन खत्म करने के लिए लेता है):
1 real 0m0.009s
2 real 0m0.009s
3 real 0m0.009s
4 real 0m0.012s
5 real 0m0.009s
Index Update - START
Index Update - FINISH
6 real 0m0.388s
7 real 0m0.009s
8 real 0m0.009s
9 real 0m0.009s
10 real 0m0.009s
11 real 0m0.009s
बनाम पढ़े गए ऑपरेशन जो ब्लॉक नहीं होते (स्क्रिप्ट में लाइन टिप्पणी स्वैप करें):
1 real 0m0.010s
2 real 0m0.009s
3 real 0m0.009s
4 real 0m0.010s
5 real 0m0.009s
Index Update - START
6 real 0m0.010s
7 real 0m0.010s
8 real 0m0.011s
9 real 0m0.010s
...
41 real 0m0.009s
42 real 0m0.010s
43 real 0m0.009s
Index Update - FINISH
44 real 0m0.012s
45 real 0m0.009s
46 real 0m0.009s
47 real 0m0.010s
48 real 0m0.009s
डाउनटाइम के बिना MySQL के स्कीमा को अपडेट करना
इस प्रकार, MySql स्कीमा को अपडेट करने के लिए केवल एक ही तरीका है जो मुझे पता है और एक उपलब्धता आउटेज से पीड़ित नहीं है। परिपत्र स्वामी:
- मास्टर A में आपका MySQL डेटाबेस चल रहा है
- मास्टर बी को सेवा में लाओ और यह मास्टर ए से लिखता है (बी ए का गुलाम है)
- मास्टर बी पर स्कीमा अपडेट करें। यह अपग्रेड के दौरान पीछे आ जाएगा
- मास्टर बी को पकड़ने दो। अपरिवर्तनीय: आपका स्कीमा परिवर्तन आवश्यक रूप से डाउनग्रेड स्कीमा से दोहराए गए आदेशों को संसाधित करने में सक्षम होना चाहिए। अनुक्रमण परिवर्तन योग्य हैं। साधारण स्तंभ परिवर्धन आमतौर पर योग्य होते हैं। कोई कॉलम निकाल रहा है? शायद ऩही।
- मुख्य रूप से मास्टर ए से मास्टर बी तक सभी ग्राहक स्वैप करते हैं। यदि आप सुरक्षित रहना चाहते हैं (मुझ पर विश्वास करें, आप करते हैं), तो आपको यह सुनिश्चित करना चाहिए कि ए को अंतिम लिखना बी BEORE को दोहराया जाए।B अपना पहला लेखन लेता है। यदि आप समवर्ती लेखन को 2+ मास्टर्स की अनुमति देते हैं, तो ... आप DEEP स्तर पर MySQL प्रतिकृति को बेहतर ढंग से समझते हैं या आप दर्द की दुनिया के लिए नेतृत्व कर रहे हैं। अत्यधिक दर्द। जैसे, क्या आपके पास एक कॉलम है जो AUTOINCREMENT है ??? आप खराब हैं (जब तक कि आप एक मास्टर पर नंबर का उपयोग नहीं करते हैं और दूसरे पर ऑड्स)। "सही काम करने के लिए" MySQL प्रतिकृति पर भरोसा न करें। यह स्मार्ट नहीं है और आपको बचाएगा नहीं। यह कमांड लाइन से द्विआधारी लेनदेन लॉग की प्रतिलिपि बनाने और हाथ से उन्हें फिर से देखने की तुलना में बस थोड़ा कम सुरक्षित है। फिर भी, पुराने मास्टर से सभी ग्राहकों को डिस्कनेक्ट करना और उन्हें नए मास्टर को फ़्लिप करना सेकंड के एक मामले में किया जा सकता है, बहु-घंटे स्कीमा उन्नयन के लिए इंतजार करने की तुलना में बहुत तेजी से।
- अब मास्टर बी आपका नया मास्टर है। आपके पास नया स्कीमा है। ज़िंदगी अच्छी है। एक बियर; सबसे खराब है।
- मास्टर ए के साथ प्रक्रिया को दोहराएं, अपने स्कीमा को अपग्रेड करें ताकि वह आपका नया माध्यमिक मास्टर बन जाए, इस घटना को संभालने के लिए तैयार कि आपका प्राथमिक मास्टर (मास्टर बी) अब शक्ति खो देता है या बस आप पर मर जाता है।
स्कीमा को अपडेट करने का एक आसान तरीका यह नहीं है। एक गंभीर उत्पादन वातावरण में व्यावहारिक; हाँ यही है। कृपया, कृपया, कृपया, अगर कोई अवरोधन के बिना MySQL तालिका में एक सूचकांक जोड़ने का एक आसान तरीका है, तो मुझे बताएं।
Googling मुझे इस लेख की ओर ले जाती है जो एक समान तकनीक का वर्णन करता है। इससे भी बेहतर, वे कार्यवाही में उसी बिंदु पर पीने की सलाह देते हैं (ध्यान दें कि मैंने लेख पढ़ने से पहले अपना जवाब लिखा था)!
पर्कोना का पीटी-ऑनलाइन-स्कीमा-परिवर्तन
लेख मैं एक उपकरण के बारे में बात करती है ऊपर लिंक, pt-ऑनलाइन-स्कीमा परिवर्तन , इस प्रकार है कि काम करता है:
- मूल के समान संरचना के साथ नई तालिका बनाएं।
- नए टेबल पर स्कीमा अपडेट करें।
- मूल तालिका पर एक ट्रिगर जोड़ें ताकि परिवर्तनों को कॉपी के साथ सिंक में रखा जाए
- मूल तालिका से बैचों में पंक्तियों की प्रतिलिपि बनाएँ।
- मूल तालिका को रास्ते से हटाएं और नई तालिका से प्रतिस्थापित करें।
- पुराना टेबल गिरा दो।
मैंने कभी भी उपकरण को स्वयं आज़माया नहीं है। YMMV
आरडीएस
मैं वर्तमान में Amazon के RDS के माध्यम से MySQL का उपयोग कर रहा हूं । यह वास्तव में एक निफ्टी सेवा है जो लपेटता है और MySQL का प्रबंधन करता है, जिससे आप एक ही बटन के साथ नई रीड प्रतिकृतियां जोड़ सकते हैं और हार्डवेयर SKU में डेटाबेस को पारदर्शी रूप से अपग्रेड कर सकते हैं। यह वास्तव में सुविधाजनक है। आपको डेटाबेस तक सुपर एक्सेस नहीं मिलती है, इसलिए आप सीधे प्रतिकृति के साथ पेंच नहीं कर सकते हैं (यह एक आशीर्वाद या अभिशाप है)। हालाँकि, आप अपने स्कीमा परिवर्तन को केवल-पढ़ने के लिए गुलाम बनाने के लिए रीड रेप्लिका प्रोमोशन का उपयोग कर सकते हैं , फिर उस दास को बढ़ावा देकर अपने नए मास्टर बन सकते हैं। बिल्कुल वैसा ही टोटका जैसा कि मैंने ऊपर वर्णित किया है, बस अमल करना बहुत आसान है। वे अभी भी कट-ओवर के साथ आपकी मदद करने के लिए बहुत कुछ नहीं करते हैं। आपको अपने ऐप को फिर से कॉन्फ़िगर और पुनरारंभ करना होगा।