[2017] Güncelleme: MySQL 5.6, çevrimiçi dizin güncellemelerini destekliyor
https://dev.mysql.com/doc/refman/8.0/en/innodb-online-ddl-operations.html#online-ddl-index-syntax-notes
MySQL 5.6 ve daha yüksek sürümlerde, dizin oluşturulurken veya bırakılırken tablo okuma ve yazma işlemleri için kullanılabilir durumda kalır. CREATE INDEX veya DROP INDEX deyimi, yalnızca tabloya erişen tüm işlemler tamamlandıktan sonra biter, böylece dizinin başlangıç durumu tablonun en son içeriğini yansıtır. Daha önce, bir dizin oluşturulurken veya bırakılırken tabloyu değiştirmek, genellikle tablodaki INSERT, UPDATE veya DELETE deyimini iptal eden bir kilitlenmeyle sonuçlanıyordu.
[2015] Tablonun güncellenmesi blokların MySQL 5.5'te yazdıklarını gösterir
Yukarıdaki cevaptan:
"Veritabanı çevrimiçiyken 5.1 indekslerden daha büyük bir sürüm kullanıyorsanız oluşturulur. Bu yüzden endişelenmeyin, üretim sistemi kullanımını kesintiye uğratmayacaksınız."
Bu **** YANLIŞ **** (en azından MyISAM / InnoDB tabloları için, oradaki insanların% 99,999'unun kullandığı şeydir. Clustered Edition farklıdır.)
Bir tablo üzerinde UPDATE işlemleri yapmak olacaktır BLOK endeks oluşturulurken. MySQL bu konuda gerçekten çok aptalca (ve birkaç başka şey).
Test Komut Dosyası:
(
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;'
Sunucum (InnoDB):
Server version: 5.5.25a Source distribution
Çıktı (dizin güncellemesini bitirmek için gereken ~ 400 ms için 6. işlemin nasıl bloke edildiğine dikkat edin):
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
Vs, engellemeyen işlemleri okuma (komut dosyasındaki satır açıklamasını değiştirin):
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'in Şemasını kesinti olmadan güncelleme
Dolayısıyla, bir MySql şemasını güncellemek ve kullanılabilirlik kesintisine uğramamak için bildiğim tek bir yöntem var. Dairesel ustalar:
- Master A, MySQL veritabanınız üzerinde çalışıyor
- Usta B'yi hizmete sokun ve Usta A'dan gelen yazıları çoğaltmasını sağlayın (B, A'nın kölesidir)
- Ana B'de şema güncellemesini gerçekleştirin. Yükseltme sırasında geride kalacak
- Bırakın Usta B yetişsin. Değişmez: Şema değişikliğiniz bir downversion şemasından çoğaltılan komutları işleyebilmelidir ZORUNLU. Dizin oluşturma değişiklikleri uygun. Basit sütun eklemeleri genellikle uygun olur. Bir sütunu kaldırmak mı? muhtemelen değil.
- Atomik olarak sen (güven bana, do), sen A'ya son yazma B'ye çoğaltılır emin olmalıdır güvenli olmasını istiyorsanız Usta B'ye Usta A'dan tüm istemcilerin takas ÖNCEB ilk yazısını alıyor. 2+ master için eşzamanlı yazma işlemlerine izin verirseniz, ... MySQL replikasyonunu DERİN seviyesinde daha iyi anlarsınız veya acı dolu bir dünyaya yönelirsiniz. Aşırı acı. Gibi, AUTOINCREMENT olan bir sütununuz var mı ??? Batırırsınız (bir ana bilgisayarda çift sayılar ve diğerinde oran kullanmadığınız sürece). MySQL replikasyonuna "doğru olanı yapmak" için GÜVENMEYİN. Akıllı DEĞİL ve seni kurtarmayacak. İkili işlem günlüklerini komut satırından kopyalayıp elle yeniden yürütmekten biraz daha az güvenlidir. Yine de, tüm istemcilerin eski ana yöneticiden bağlantısını kesmek ve onları yeni ana yöneticiye çevirmek, birkaç saatlik bir şema yükseltmesini beklemekten çok daha hızlı bir şekilde saniyeler içinde yapılabilir.
- Şimdi Usta B yeni üstadınız. Yeni şemaya sahipsiniz. Hayat güzel. Bir bira iç; en kötüsü bitti.
- Süreci Usta A ile tekrarlayın, şemasını yeni ikincil üstadınız olacak şekilde yükseltin, birincil ustanızın (şimdi usta B) gücünü kaybetmesi veya sadece sizin üzerinizden ölmesi durumunda devralmaya hazır.
Şemayı güncellemenin kolay bir yolu bu değil. Ciddi bir üretim ortamında uygulanabilir; Evet öyle. Lütfen, lütfen, lütfen, yazmaları engellemeden bir MySQL tablosuna dizin eklemenin daha kolay bir yolu varsa, bana bildirin.
Googling beni benzer bir tekniği anlatan bu makaleye yönlendiriyor. Daha da iyisi, işlemde aynı noktada içmeyi tavsiye ediyorlar (Cevabımı makaleyi okumadan önce yazdığımı unutmayın)!
Percona'nın pt-çevrimiçi-şema değişikliği
Makale Bir araç hakkında görüşmelerde yukarıda bağlantılı, pt-online-şema değişikliği , yani aşağıdaki gibi çalışır:
- Orijinalle aynı yapıya sahip yeni tablo oluşturun.
- Yeni tabloda şemayı güncelleyin.
- Orijinal tabloya bir tetikleyici ekleyin, böylece değişikliklerin kopyayla senkronize kalması
- Orijinal tablodan gruplar halinde satırları kopyalayın.
- Orijinal masayı ortadan kaldırın ve yeni masayla değiştirin.
- Eski masayı bırak.
Aracı kendim hiç denemedim. YMMV
RDS
Şu anda Amazon'un RDS'si aracılığıyla MySQL kullanıyorum . MySQL'i tamamlayan ve yöneten, tek bir düğmeyle yeni okuma replikaları eklemenize ve veritabanını donanım SKU'ları arasında şeffaf bir şekilde yükseltmenize olanak tanıyan gerçekten şık bir hizmettir. Gerçekten uygun. Veritabanına SÜPER erişim elde edemezsiniz, bu nedenle doğrudan çoğaltma ile uğraşamazsınız (bu bir lütuf mu yoksa lanet mi?). Bununla birlikte, salt okunur bir slave üzerinde şema değişikliklerinizi yapmak için Read Replica Promosyonu kullanabilir ve ardından bu slave'i yeni master'ınız haline getirebilirsiniz. Yukarıda anlattığımla tamamen aynı numara, uygulanması çok daha kolay. Hâlâ kesim konusunda size yardımcı olacak pek bir şey yapmıyorlar. Uygulamanızı yeniden yapılandırmanız ve yeniden başlatmanız gerekiyor.