MySQL репликацията е много популярен начин за изграждане на високодостъпни слоеве на база данни. Той е много добре познат, изпитан и здрав. Не е без ограничения обаче. Едно от тях определено е фактът, че използва само една „входна точка“ – имате специален сървър в топологията, главния, и това е единственият възел в клъстера, към който можете да издавате записи. Това води до тежки последици - главният е единствената точка на отказ и ако не успее, приложението не може да изпълни запис. Не е изненада, че е положена много работа в разработването на инструменти, които биха намалили въздействието от основна загуба. Разбира се, има дискусии как да се подходи към темата, по-добро ли е автоматичното преминаване при отказ от ръчното или не. В крайна сметка това е бизнес решение, което трябва да вземете, но ако решите да следвате пътя на автоматизацията, ще търсите инструментите, които да ви помогнат да постигнете това. Един от инструментите, който все още е много популярен, е MHA (Master High Availability). Макар че може би вече не се поддържа активно, той все още е в стабилна форма и огромната му популярност все още го прави гръбнак на високодостъпните настройки за репликация на MySQL. Какво ще се случи обаче, ако самата MHA стане недостъпна? Може ли да се превърне в единична точка на провал? Има ли начин да се предотврати това да се случи? В тази публикация в блога ще разгледаме някои от сценариите.
Първо, ако планирате да използвате MHA, уверете се, че използвате най-новата версия от репо. Не използвайте двоични издания, тъй като те не съдържат всички корекции. Инсталацията е сравнително проста. MHA се състои от две части, мениджър и възел. Node трябва да бъде разгърнат на вашите сървъри на база данни. Мениджърът ще бъде разположен на отделен хост, заедно с възел. И така, сървъри на база данни:възел, хост за управление:мениджър и възел.
Съставянето на MHA е доста лесно. Отидете до GitHub и клонирайте хранилищата.
https://github.com/yoshinorim/mha4mysql-manager
https://github.com/yoshinorim/mha4mysql-node
Тогава всичко е за:
perl Makefile.PL
make
make install
Може да се наложи да инсталирате някои Perl зависимости, ако вече нямате инсталирани всички необходими пакети. В нашия случай, на Ubuntu 16.04, трябваше да инсталираме следното:
perl -MCPAN -e "install Config::Tiny"
perl -MCPAN -e "install Log::Dispatch"
perl -MCPAN -e "install Parallel::ForkManager"
perl -MCPAN -e "install Module::Install"
След като инсталирате MHA, трябва да го конфигурирате. Тук няма да навлизаме в подробности, има много ресурси в интернет, които покриват тази част. Примерна конфигурация (определено непроизводствена) може да изглежда така:
[email protected]:~# cat /etc/app1.cnf
[server default]
user=cmon
password=pass
ssh_user=root
# working directory on the manager
manager_workdir=/var/log/masterha/app1
# working directory on MySQL servers
remote_workdir=/var/log/masterha/app1
[server1]
hostname=node1
candidate_master=1
[server2]
hostname=node2
candidate_master=1
[server3]
hostname=node3
no_master=1
Следващата стъпка ще бъде да видите дали всичко работи и как MHA вижда репликацията:
[email protected]:~# masterha_check_repl --conf=/etc/app1.cnf
Tue Apr 9 08:17:04 2019 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
Tue Apr 9 08:17:04 2019 - [info] Reading application default configuration from /etc/app1.cnf..
Tue Apr 9 08:17:04 2019 - [info] Reading server configuration from /etc/app1.cnf..
Tue Apr 9 08:17:04 2019 - [info] MHA::MasterMonitor version 0.58.
Tue Apr 9 08:17:05 2019 - [error][/usr/local/share/perl/5.22.1/MHA/MasterMonitor.pm, ln427] Error happened on checking configurations. Redundant argument in sprintf at /usr/local/share/perl/5.22.1/MHA/NodeUtil.pm line 195.
Tue Apr 9 08:17:05 2019 - [error][/usr/local/share/perl/5.22.1/MHA/MasterMonitor.pm, ln525] Error happened on monitoring servers.
Tue Apr 9 08:17:05 2019 - [info] Got exit code 1 (Not master dead).
Е, разби се. Това е така, защото MHA се опитва да анализира версията на MySQL и не очаква тирета в нея. За щастие, корекцията е лесна за намиране:https://github.com/yoshinorim/mha4mysql-manager/issues/116.
Сега имаме MHA, готов за работа.
[email protected]:~# masterha_manager --conf=/etc/app1.cnf
Tue Apr 9 13:00:00 2019 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
Tue Apr 9 13:00:00 2019 - [info] Reading application default configuration from /etc/app1.cnf..
Tue Apr 9 13:00:00 2019 - [info] Reading server configuration from /etc/app1.cnf..
Tue Apr 9 13:00:00 2019 - [info] MHA::MasterMonitor version 0.58.
Tue Apr 9 13:00:01 2019 - [info] GTID failover mode = 1
Tue Apr 9 13:00:01 2019 - [info] Dead Servers:
Tue Apr 9 13:00:01 2019 - [info] Alive Servers:
Tue Apr 9 13:00:01 2019 - [info] node1(10.0.0.141:3306)
Tue Apr 9 13:00:01 2019 - [info] node2(10.0.0.142:3306)
Tue Apr 9 13:00:01 2019 - [info] node3(10.0.0.143:3306)
Tue Apr 9 13:00:01 2019 - [info] Alive Slaves:
Tue Apr 9 13:00:01 2019 - [info] node2(10.0.0.142:3306) Version=5.7.25-28-log (oldest major version between slaves) log-bin:enabled
Tue Apr 9 13:00:01 2019 - [info] GTID ON
Tue Apr 9 13:00:01 2019 - [info] Replicating from 10.0.0.141(10.0.0.141:3306)
Tue Apr 9 13:00:01 2019 - [info] Primary candidate for the new Master (candidate_master is set)
Tue Apr 9 13:00:01 2019 - [info] node3(10.0.0.143:3306) Version=5.7.25-28-log (oldest major version between slaves) log-bin:enabled
Tue Apr 9 13:00:01 2019 - [info] GTID ON
Tue Apr 9 13:00:01 2019 - [info] Replicating from 10.0.0.141(10.0.0.141:3306)
Tue Apr 9 13:00:01 2019 - [info] Not candidate for the new Master (no_master is set)
Tue Apr 9 13:00:01 2019 - [info] Current Alive Master: node1(10.0.0.141:3306)
Tue Apr 9 13:00:01 2019 - [info] Checking slave configurations..
Tue Apr 9 13:00:01 2019 - [info] Checking replication filtering settings..
Tue Apr 9 13:00:01 2019 - [info] binlog_do_db= , binlog_ignore_db=
Tue Apr 9 13:00:01 2019 - [info] Replication filtering check ok.
Tue Apr 9 13:00:01 2019 - [info] GTID (with auto-pos) is supported. Skipping all SSH and Node package checking.
Tue Apr 9 13:00:01 2019 - [info] Checking SSH publickey authentication settings on the current master..
Tue Apr 9 13:00:02 2019 - [info] HealthCheck: SSH to node1 is reachable.
Tue Apr 9 13:00:02 2019 - [info]
node1(10.0.0.141:3306) (current master)
+--node2(10.0.0.142:3306)
+--node3(10.0.0.143:3306)
Tue Apr 9 13:00:02 2019 - [warning] master_ip_failover_script is not defined.
Tue Apr 9 13:00:02 2019 - [warning] shutdown_script is not defined.
Tue Apr 9 13:00:02 2019 - [info] Set master ping interval 3 seconds.
Tue Apr 9 13:00:02 2019 - [warning] secondary_check_script is not defined. It is highly recommended setting it to check master reachability from two or more routes.
Tue Apr 9 13:00:02 2019 - [info] Starting ping health check on node1(10.0.0.141:3306)..
Tue Apr 9 13:00:02 2019 - [info] Ping(SELECT) succeeded, waiting until MySQL doesn't respond..
Както можете да видите, MHA следи нашата топология на репликация, като проверява дали главният възел е наличен или не. Нека разгледаме няколко сценария.
Сценарий 1 – MHA се срина
Да предположим, че MHA не е наличен. Как това се отразява на околната среда? Очевидно, тъй като MHA е отговорен за наблюдението на здравето на капитана и задействане на отказ, това няма да се случи, когато MHA не работи. Главният срив няма да бъде открит, преминаването при отказ няма да се случи. Проблемът е, че наистина не можете да стартирате няколко MHA екземпляра едновременно. Технически можете да го направите, въпреки че MHA ще се оплаче от файл за заключване:
[email protected]:~# masterha_manager --conf=/etc/app1.cnf
Tue Apr 9 13:05:38 2019 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
Tue Apr 9 13:05:38 2019 - [info] Reading application default configuration from /etc/app1.cnf..
Tue Apr 9 13:05:38 2019 - [info] Reading server configuration from /etc/app1.cnf..
Tue Apr 9 13:05:38 2019 - [info] MHA::MasterMonitor version 0.58.
Tue Apr 9 13:05:38 2019 - [warning] /var/log/masterha/app1/app1.master_status.health already exists. You might have killed manager with SIGKILL(-9), may run two or more monitoring process for the same application, or use the same working directory. Check for details, and consider setting --workdir separately.
Той обаче ще започне и ще се опита да наблюдава околната среда. Проблемът е, когато и двамата започнат да изпълняват действия в клъстера. По-лошият случай би бил, ако решат да използват различни подчинени като главен кандидат и отказът ще се изпълни едновременно (MHA използва файл за заключване, който предотвратява последващи откази да се случват, но ако всичко се случи едновременно и се случи в нашия тестове, тази мярка за сигурност не е достатъчна).
За съжаление няма вграден начин за управление на MHA по високодостъпен начин. Най-простото решение ще бъде да напишете скрипт, който да тества дали MHA работи и ако не, да го стартирате. Такъв скрипт би трябвало да се изпълни от cron или да бъде написан под формата на демон, ако 1 минута детайлност на cron не е достатъчна.
Сценарий 2 – MHA мениджър възел, изгубена мрежова връзка с главния
Нека бъдем честни, това е наистина лоша ситуация. Веднага щом MHA не може да се свърже с главния, той ще се опита да извърши отказ. Единственото изключение е, ако secondary_check_script е дефиниран и той потвърди, че главният е жив. От потребителя зависи да дефинира точно какви действия трябва да извърши MHA, за да провери статуса на капитана - всичко зависи от средата и точната настройка. Друг много важен скрипт за дефиниране е master_ip_failover_script - това се изпълнява при отказ и трябва да се използва, наред с другото, за да се гарантира, че старият главен код няма да се покаже. Ако случайно имате достъп до допълнителни начини за достигане и спиране на стария господар, това е наистина страхотно. Това може да бъде инструменти за дистанционно управление като Integrated Lights-out, може да бъде достъп до управляеми електрически контакти (където можете просто да изключите сървъра), може да бъде достъп до CLI на доставчика на облак, което ще направи възможно спирането на виртуалния екземпляр . От изключителна важност е да спрете стария господар - в противен случай може да се случи, че след като проблемът с мрежата изчезне, ще се окажете с два възела за запис в системата, което е идеално решение за разделения мозък, състояние, при което данните се разминават между две части от един и същ клъстер.
Както можете да видите, MHA може да се справи доста добре с отказването на MySQL. Определено изисква внимателна конфигурация и ще трябва да пишете външни скриптове, които ще бъдат използвани, за да убият стария господар и да гарантират, че разделянето на мозъка няма да се случи. Като казахме това, ние все пак бихме препоръчали да използвате по-усъвършенствани инструменти за управление на отказ като Orchestrator или ClusterControl, които могат да извършват по-усъвършенстван анализ на състоянието на топологията на репликация (например чрез използване на подчинени или прокси сървъри за оценка на наличността на главния) и които са и ще се поддържа и в бъдеще. Ако се интересувате да научите как ClusterControl извършва преодоляване на срив, бихме искали да ви поканим да прочетете тази публикация в блога за процеса на отказ в ClusterControl. Можете също да научите как ClusterControl взаимодейства с ProxySQL, осигурявайки плавно, прозрачно преминаване на отказ за вашето приложение. Винаги можете да тествате ClusterControl, като го изтеглите безплатно.