MySQL Master-Slave Master nasıl belirlenir


17

MySQL Master-slave replikasyonunu kuruyorum ve slave'i master'a yükselttiğimde yük devretme durumunu nasıl ele alacağımı anlamaya çalışıyorum (master düşerse).

Uygulama sunucumun tüm yazmaları geçerli master'a yönlendirmesi gerekiyor, ancak master ve slave (kalp atışı, keepalived) arasında sunucu seviyesi HA'yı kullanamıyorum çünkü iki db sunucusu farklı fiziksel konumlarda tamamen farklı alt ağlarda.

Bunun uygulama düzeyinde ele almam gereken bir şey olduğunu düşünüyorum. İki sunucuyu sorgulayabilir ve hangisinin bir ana olduğunu sorabilirim, sonra tüm sorguları bu sunucuya uygulayabilirim.

Geçerli sunucunun bir master-slave kopyasında master olup olmadığını görmek için MySQL'de bir sorgu var mı?


Hangi MySQL sürümünü kullanıyorsunuz ???
RolandoMySQLDBA

Bu mysql çıktıServer version: 5.5.23 MySQL Community Server (GPL)
Ethan Hayon

Yanıtlar:


13

@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 STATUStam 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, SUPERayrı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 = OFFyazma 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_safeNezaketle yeniden başlar mysqldve 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.processlistana 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 SLAVEbu 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/hostsdosyası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.


Her şeyden önce, iyi yazılmış yanıt için teşekkür ederim. Bence iyi bir çözüm önerdin. Geçmişte dairesel çoğaltma kullanmayı düşündüm, ancak güvenilirliği ile ilgili kötü şeyler okudum. Ancak, bu sorunların çoğu auto_increment_increment, auto_increment_offset, vb. Değiştirilerek önlenebilir. HAProxy'yi uygulama sunucularında yerel olarak kullanmak (yalnızca yük devretme olarak) uygulamamızı değiştirmek zorunda kalmayacağımız için bizim için iyi çalışır, bu nedenle yük devretmeyi soyutlayabiliriz. uygulama katmanından uzak mantık. HAProxy'yi yapılandırmaya bakacağım, teşekkürler!
Ethan Hayon

1
Yardımcı olduğuma sevindim. Henüz yapmadıysanız bir oylama takdir edilecektir. Dairesel çoğaltma, nasıl çalıştığını anladığınız ve mantıklı bir şekilde kullandığınız sürece, master / slave kadar güvenilirdir (aynı teknoloji, her iki yöne de gider). Sunucular düzgün bir şekilde senkronize edildiği ve uygulama aynı anda yalnızca bir sunucuya yazdığı sürece, onunla hiç bir sorun yaşamadım. auto_increment_*Değişkenler "her ihtimale karşı.", Yine bu senaryoda kullanmak iyidir Ayrıca, binlog_format= rowveya mixed- not kullanmayı da statement(dairesel yapmasanız bile) unutmayın.
Michael - sqlbot

Kabul edilen cevabı tamamen değiştirdim, çünkü bu ayrıntılı açıklama sistemi daha sağlam hale getirmeme yardımcı oldu. @ RolandoMySQLDBA'nın cevabı hala doğru ve başlangıçta tarif ettiğim problemi çözüyor. Teşekkürler!
Ethan Hayon

10

Yalnızca Master / Slave kullanıyorsanız, işte hızlı ve kirli bir şey:

SELECT COUNT(1) SlaveThreadCount
FROM information_schema.processlist
WHERE user='system user';

Bu size ne anlatıyor?

  • Eğer SlaveThreadCount= 0, sen ustan var
  • Eğer SlaveThreadCount0>, sen Slave var

CAVEAT : Çalışmadıkça çalışırSTOP SLAVE;

Denenecek başka bir şey şudur: Slave'de ikili günlük kaydını devre dışı bırakır ve çalıştırırsanız SHOW MASTER STATUS;, Master size geçerli ikili günlüğü verir. Köle sana hiçbir şey vermez.


Harika, tam da ihtiyacım olan şey bu. Bunun soruna dağınık bir çözüm olduğunu düşünüyor musunuz? Tahmin edebileceğim tek sorun, her iki sunucunun da master'a yükseltilmesidir, ancak bu aslında olmamalıdır.
Ethan Hayon

Bu yanıt ihtiyacınız olan şeyse, lütfen cevabımdaki onay işaretini tıklayarak kabul edilen yanıtı işaretleyin.
RolandoMySQLDBA

5 dakika daha kabul edildi olarak işaretleyemem :)
Ethan Hayon

Sorun değil. Ben yardımcı olabilir sevindim !!!
RolandoMySQLDBA

0

bu ifadeyi mysql komut isteminden yürüt
mysql> köle durumunu göster;

Slave'de çok sayıda parametre ve değerlerini / durumlarını gösterirken master'da Boş küme gösterir

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.