[2017] अपडेट:MySQL 5.6 में ऑनलाइन इंडेक्स अपडेट के लिए सपोर्ट है
<ब्लॉकक्वॉट>MySQL 5.6 और उच्चतर में, तालिका पढ़ने और लिखने के संचालन के लिए उपलब्ध रहती है, जबकि सूचकांक बनाया या गिराया जा रहा है। CREATE INDEX या DROP INDEX स्टेटमेंट टेबल तक पहुँचने वाले सभी लेन-देन के पूरा होने के बाद ही समाप्त होता है, ताकि इंडेक्स की प्रारंभिक स्थिति तालिका की सबसे हाल की सामग्री को दर्शाती है। पहले, जब कोई इंडेक्स बनाया या गिराया जाता है, तो टेबल को संशोधित करने से आम तौर पर एक गतिरोध उत्पन्न होता है जो टेबल पर INSERT, UPDATE, या DELETE स्टेटमेंट को रद्द कर देता है।
[2015] MySQL 5.5 में टेबल इंडेक्स ब्लॉक्स को अपडेट करना
ऊपर दिए गए उत्तर से:
<ब्लॉकक्वॉट>"यदि डेटाबेस के ऑनलाइन होने के दौरान आप 5.1 से अधिक के संस्करण का उपयोग कर रहे हैं तो सूचकांक बनाए जाते हैं। तो चिंता न करें आप उत्पादन प्रणाली के उपयोग को बाधित नहीं करेंगे।"
यह ****गलत**** है (कम से कम MyISAM / InnoDB तालिकाओं के लिए, जो कि 99.999% लोग उपयोग करते हैं। क्लस्टर संस्करण अलग है।)
किसी टेबल पर UPDATE ऑपरेशन करने से ब्लॉक हो जाएगा जबकि सूचकांक बनाया जा रहा है। 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 डेटाबेस चल रहा है
- मास्टर बी को सेवा में लाएं और मास्टर ए (बी ए का गुलाम है) के लेखन को दोहराएं
- मास्टर बी पर स्कीमा अपडेट करें। यह अपग्रेड के दौरान पीछे रह जाएगा
- मास्टर बी को पकड़ने दें। अपरिवर्तनीय:आपका स्कीमा परिवर्तन डाउनवर्जन स्कीमा से दोहराए गए आदेशों को संसाधित करने में सक्षम होना चाहिए। अनुक्रमण परिवर्तन योग्य हैं। साधारण कॉलम जोड़ आमतौर पर योग्य होते हैं। एक कॉलम हटा रहा है? शायद ऩही।
- एटोमिकली सभी क्लाइंट को मास्टर ए से मास्टर बी में स्वैप करें। यदि आप सुरक्षित रहना चाहते हैं (मुझ पर विश्वास करें, तो आप करते हैं), आपको यह सुनिश्चित करना चाहिए कि ए को अंतिम लेखन बी पहले के लिए दोहराया गया है। बी अपना पहला लेखन लेता है। यदि आप 2+ मास्टर्स को समवर्ती लिखने की अनुमति देते हैं, ... आप DEEP स्तर पर MySQL प्रतिकृति को बेहतर ढंग से समझते हैं या आप दर्द की दुनिया के लिए नेतृत्व कर रहे हैं। अत्यधिक दर्द। जैसे, क्या आपके पास एक कॉलम है जो कि AUTOINCREMENT है??? आप खराब हो गए हैं (जब तक कि आप एक मास्टर पर सम संख्याओं और दूसरे पर ऑड्स का उपयोग नहीं करते हैं)। "सही काम करने" के लिए MySQL प्रतिकृति पर भरोसा न करें। यह स्मार्ट नहीं है और आपको नहीं बचाएगा। यह कमांड-लाइन से बाइनरी ट्रांजैक्शन लॉग को कॉपी करने और उन्हें हाथ से फिर से चलाने की तुलना में थोड़ा कम सुरक्षित है। फिर भी, पुराने मास्टर से सभी क्लाइंट को डिस्कनेक्ट करना और उन्हें नए मास्टर पर फ़्लिप करना कुछ ही सेकंड में किया जा सकता है, जो एक बहु-घंटे स्कीमा अपग्रेड की प्रतीक्षा करने से कहीं अधिक तेज़ है।
- अब मास्टर बी आपका नया मास्टर है। आपके पास नई स्कीमा है। जीवन अच्छा है। एक बियर; सबसे बुरा खत्म हो गया है।
- मास्टर ए के साथ प्रक्रिया को दोहराएं, उसकी स्कीमा को अपग्रेड करें ताकि वह आपका नया माध्यमिक मास्टर बन जाए, इस घटना में आपके प्राथमिक मास्टर (मास्टर बी अभी) शक्ति खो देता है या बस ऊपर और आप पर मर जाता है। ली>
स्कीमा को अपडेट करने का एक आसान तरीका यह नहीं है। एक गंभीर उत्पादन वातावरण में व्यावहारिक; हां यह है। कृपया, कृपया, कृपया, यदि लिखने को अवरुद्ध किए बिना किसी MySQL तालिका में अनुक्रमणिका जोड़ने का कोई आसान तरीका है, तो मुझे बताएं।
Percona's pt-online-schema-change
लेख मैंने ऊपर एक टूल के बारे में बातचीत को लिंक किया है, pt -ऑनलाइन-स्कीमा-परिवर्तन , जो इस प्रकार काम करता है:
- मूल संरचना वाली नई तालिका बनाएं।
- नई तालिका पर स्कीमा अपडेट करें।
- मूल तालिका में एक ट्रिगर जोड़ें ताकि परिवर्तनों को प्रतिलिपि के साथ समन्वयित रखा जा सके
- पंक्तियों को मूल तालिका से बैचों में कॉपी करें।
- मूल तालिका को रास्ते से हटा दें और नई तालिका से बदलें।
- पुरानी तालिका छोड़ें।
मैंने कभी खुद टूल की कोशिश नहीं की है। वाईएमएमवी
आरडीएस
मैं वर्तमान में Amazon's RDS के माध्यम से MySQL का उपयोग कर रहा हूं . यह वास्तव में एक अच्छी सेवा है जो MySQL को लपेटती है और प्रबंधित करती है, जिससे आप एक बटन के साथ नई रीड प्रतिकृतियां जोड़ सकते हैं और हार्डवेयर एसकेयू में डेटाबेस को पारदर्शी रूप से अपग्रेड कर सकते हैं। यह वास्तव में सुविधाजनक है। आपको डेटाबेस तक सुपर एक्सेस नहीं मिलता है, इसलिए आप सीधे प्रतिकृति के साथ पेंच नहीं कर सकते (क्या यह एक आशीर्वाद या अभिशाप है?) हालांकि, आप प्रतिकृति प्रचार पढ़ें केवल-पढ़ने के लिए दास पर अपनी स्कीमा परिवर्तन करने के लिए, फिर उस दास को अपना नया स्वामी बनने के लिए बढ़ावा दें। जैसा कि मैंने ऊपर वर्णित किया है, बिल्कुल वही चाल निष्पादित करने में काफी आसान है। कट-ओवर में आपकी मदद करने के लिए वे अभी भी बहुत कुछ नहीं करते हैं। आपको अपने ऐप को फिर से कॉन्फ़िगर और पुनरारंभ करना होगा।