@RolandoMySQLDBA soruyu doğru bir şekilde yanıtladı ... ancak çözümünün "hızlı ve kirli" olduğuna dikkat çekti.
Ve bu çok doğru bir ifade. :)
Burada beni ilgilendiren şey bu cevapta değil, asıl sorunun yanlış bir varsayım yaptığı görülüyor:
İki sunucuyu sorgulayabilir ve hangisinin bir ana olduğunu sorabilirim, sonra tüm sorguları bu sunucuya uygulayabilirim.
Sorun şu ki, MySQL çoğaltmasında master asla master olduğunun farkında değildir.
"Ustaya yükselme" kavramı aslında MySQL asenkron çoğaltmasında bir kavram değildir. Bir MySQL sunucusunu ana role "yükseltmek", MySQL sunucularına "dahili" olan bir şeyin tersine, "MySQL sunucularının dışında" gerçekleşen bir şeydir.
"Master'a yükselme" herhangi bir sunucu provizyonu tarafından yapılmaz, çünkü teknik olarak, ikili günlük kaydı etkinleştirilmiş olan her MySQL sunucusu bir köle olmasa bile bir master'dır. SHOW MASTER STATUS
tam olarak aynı şekilde çalışır ve tam olarak aynı sonucu döndürür, köle olsun veya olmasın ve 2 köle olan bir usta, 1 köle veya 0 köle olan bir ustadan daha fazla veya daha az bir usta değildir. Benzer şekilde, köleleri tamamen çevrimdışı olan bir usta hala bir ustadır, çünkü köleler tekrar çevrimiçi olduklarında, kaldıkları yerde çoğaltırlar.
Bir anlamda, her iki sunucunun da tek "farkındalığı", sunucunun bir yönetici olup olmadığı değil, bir köle (ya da "değil") olmasıdır.
Rolando'nun çözümü şöyle soruyor: "Sen bir köle misin?" Cevap hayırsa, varsayım bunun ustası olması gerektiğidir ... ki eğer STOP SLAVE;
yayınlanırsa da kusurlu bir varsayım olarak işaret etti . Fakat durdurulan bir köle hala bir köle, bu yüzden "köle değil" (herhangi bir zamanda) "usta olmak" demek değildir.
Benzer bir test, varsayılan master üzerinde yapılabilir:
SELECT COUNT(1) FROM information_schema.processlist
WHERE user = 'the_username_used_by_the_slave';
veya
SELECT COUNT(1) FROM information_schema.processlist
WHERE command = 'binlog dump';
Değer sıfırsa, ikincil öğenin IO iş parçacığı bağlı değildir. Bu testin benzer bir kusuru vardır, çünkü köle yönetimsel olarak kesilirse, yalıtılırsa veya başarısız olursa, bağlanmaz. Yani bu da hiçbir şeyi çözmez.
Daha da kötüsü (bu senaryoların her ikisi için) information_schema.processlist "table" her seçilişinde gerçekleşen sanal bir tablodur ve bu zaman ve maliyet gerektirir. Sunucunuz ne kadar yoğun olursa, maliyeti o kadar artar, çünkü her bir iş parçacığının etkinliği gözetilmelidir.
Daha hafif bir çözüm:
SELECT @@global.read_only;
Bir köle üzerinde, global değişkeni read_only
, SUPER
ayrıcalığı olmayan kullanıcıların istemeden ona yazamayacağı şekilde ayarlayabilirsiniz (ve uygulamanızda olmamalıdır SUPER
). Slave'i ana role manuel olarak "tanıtırsanız", SET GLOBAL read_only = OFF
yazma işlemlerini etkinleştirebilirsiniz. (Bu ayar ne olursa olsun, çoğaltma her zaman slave'e yazabilir).
Ama bu hala bence önemli bir noktayı kaçırıyor:
Başvurunun bu kararı sezgisel olarak bir master / slave kurulumunda değil, kesinlikle bağlantı bazında yapmaması gerektiğini öneriyorum. Uygulama bir sabit yapılandırma seçeneği kullanmalı veya uygulama farkında kalmamalı ve veritabanı bağlantı hedefinin başka bir şey tarafından işlenmesini sağlamalıdır.
Ya da, en azından, uygulama master başarısız olana kadar asla geçiş yapmamalı ve daha sonra asla kendi başına geri dönmemelidir.
Neden şunu söylüyorum: "karar" - kim veya ne olursa olsun - başka bir sunucuyu yönetici yapmak için yapıldıktan sonra, uygulamanın tekrar çevrimiçi olduktan sonra bile orijinal yöneticiye geri dönmesine izin verilemez. , müdahale olmadan.
Diyelim ki bir hataya çarptınız ve yazılım tarafından zorlanan bir kilitlenme var; mysqld_safe
Nezaketle yeniden başlar mysqld
ve InnoDB çökme kurtarma kusursuz bir performans sergiliyor. Ama bu birkaç dakika sürüyor.
Bu arada, master çöktü, bu yüzden başvurunuz slave'e geçti. İşlemler yaratıldı, verilen siparişler, transfer edilen fonlar, gönderilen yorumlar, bloglar düzenlendi, sisteminiz ne yaparsa yapın.
Şimdi, orijinal usta tekrar çevrimiçi oluyor.
Uygulamanız orijinal master'a geri dönerse, mutlak bir incinme dünyasındasınız, çünkü gerçekleşmesi muhtemel bir sonraki şey, çoğaltmanın tutarsızlık nedeniyle durmasıdır, çünkü uygulamanız ortalama olarak köle üzerindeki verileri değiştirmiştir. saati. Artık el ile eşitlemek zorunda kalacağınız verileri tutarsız iki veritabanı sunucunuz var. Eğer dolar veya puan veya kredi varsa, artık tutarsız bakiyeniz var.
Bu nedenle, müdahaleniz olmadan uygulamanın orijinal master'a geri dönmesine izin verilmemesi önemlidir.
Bekle, açıkladığım gibi bu senaryodaki sorunu buldun mu? Master başarısız oldu, ancak uygulamanız slave'i kullanmayacak, çünkü slave hala slave değil slave olduğunu düşünüyor ... information_schema.processlist
ana sunucu kapatılsa bile slave'deki sorgu hala sıfırdan farklı bir şekilde dönecek .
Bu yüzden uygulamada hiçbir şey keşfetmenin pek bir anlamı yoktur, çünkü STOP SLAVE
bu testin yararlı olması için manuel olarak yapmanız gerekir .
Uygulamanın değiştirilebilmesini istiyorsanız, sunucuları dairesel çoğaltma ile yapılandırmak daha iyi bir yaklaşım olabilir.
Dairesel çoğaltmanın kendine özgü sorunları vardır, ancak uygulamanız her seferinde yalnızca bir sunucuya yazdığı sürece, bu sorunların çoğu sorun olmaz. Diğer bir deyişle, her iki makine de her zaman ve eşzamanlı olarak hem ana hem de bağımlıdır, çoğaltma anlamındadır, ancak uygulamanız bazı mekanizmalarla her zaman yalnızca bir makineye yazabileceği ve yazması gereken "ana" olarak işaret ediyor .
Ayrıldıkları için HA araçlarını MySQL sunucularına dağıtamazsınız, ancak uygulama sunucu (lar) ında çalışan HAProxy ile uygulayabilirsiniz. Uygulama yerel ana bilgisayardaki "MySQL" e bağlanıyor, ki bu MySQL değil, aslında HAProxy ... ve TCP bağlantısını uygun MySQL makinesine iletiyor.
HAProxy, MySQL sunucularına bağlantıları test edebilir ve yalnızca bağlantıları kabul eden ve kimlik doğrulamasına izin veren bir MySQL makinesine trafik sunabilir.
Uygulama sunucusunda çalışan HAProxy'nin kombinasyonu (kaynak talebi, uygulama sunucusunun yapması gereken her şeyle karşılaştırıldığında önemli olmayacaktır - hemen hemen yuvaları birbirine bağlamak ve yüklerini yok saymak) ... ve MySQL dairesel çoğaltması sorudan bilinenlere dayanarak bu durumda alacağım yaklaşım olurdu.
Ya da, kesinlikle manuel bir kurulum için, uygulama sunucusunun /etc/hosts
dosyasındaki, uygulamanın manuel olarak güncelleyebileceğiniz MySQL'e bağlanmak için kullandığı bir ana bilgisayar adına sahip bir giriş gibi "keşif" ten çok daha basit bir şeyle gidin - köle tanıtımı varsayarak master manuel bir işlem olarak tasarlanmıştır.
Veya Percona XtraDB Kümesi'ni kullanarak daha karmaşık bir şey. Bununla birlikte, bunun için üçüncü bir sunucu eklemek istersiniz, çünkü PXC'deki 3 düğümle, 2 sunucu birbirini görebilir ancak 1 sunucudan izole edilebilirse (üçü hala çalışıyorsa) 2 sunucu mutlu bir şekilde çalışmaya devam eder, ancak 1 sunucu küçük bir topa kıvrılıyor ve garip olanı fark ettiğinden herhangi bir şey yapmayı reddediyor. Bu işe yarıyor çünkü ikisi ağ bölünmeden önce çevrimiçi olan düğümlerin çoğunluğunu oluşturduğunu ve 1'in bunun olmadığını fark ettiğini fark ediyor. PXC ile, uygulamanızın hangi sunucuya bağlandığı önemli değildir.
Ben tüm bu "er ya da geç ısırmak için ısırmak ve ısırdığı güne kadar performans nibble olacak çünkü" uygulama hangisinin usta görmek yok anket yok "demek olduğunu söylüyorlar.