但凡是MySQL DBA肯定都聽說過MHA個高可用方案,而且很多公司都是通過對MHA做二次開發(fā)來實現(xiàn)MySQL高可用的。如果MHA不結(jié)合VIP的話,每次主庫切換都需要程序修改連數(shù)據(jù)庫的配置,這樣比較麻煩。而采用MHA+VIP的方式時可以在主庫切換的過程中讓VIP漂移到新主庫,省去了改數(shù)據(jù)庫配置這一過程。
臺兒ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場景,ssl證書未來市場廣闊!成為創(chuàng)新互聯(lián)的ssl證書銷售渠道,可以享受市場價格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:18982081108(備注:SSL證書合作)期待與您的合作!
公司以前是每一組主從復(fù)制集群都配置一個manager結(jié)點(diǎn),然后將vip和網(wǎng)絡(luò)接口等信息都寫死在master_ip_failover和master_ip_online_change腳本中。當(dāng)主從集群數(shù)量太多的情況下要維護(hù)的manager結(jié)點(diǎn)很多,管理起來很麻煩。
如何實現(xiàn)用一個Manager結(jié)點(diǎn)管理多個支持VIP的mysql主從集群呢?有兩種實現(xiàn)方式:
1,每一組主從復(fù)制集群維護(hù)兩個切換腳本,將VIP和網(wǎng)絡(luò)接口信息寫死在腳本里。
2,修改MHA的相關(guān)模塊,使其能識別我們自定義的參數(shù),我們只需要在每一組主從復(fù)制集群的配置文件中給參數(shù)傳值。
很明顯,第1種方式太low了,需要維護(hù)大量的切換腳本。那我們需要修改哪些模塊呢?
看一下masterha_check_repl這段腳本,可以看到檢測主從復(fù)制狀態(tài)的時候會調(diào)用MasterMonitor模塊。
$exit_code = MHA::MasterMonitor::main( "--interactive=0", "--check_only", "--check_repl_health", @ARGV ); if ( $exit_code == 0 ) { print "\nMySQL Replication Health is OK.\n"; } else { print "\nMySQL Replication Health is NOT OK!\n"; }
通過masterha_master_switch這段腳本可以看到在線切換是調(diào)用的MasterRotate模塊,故障切換是調(diào)用的MasterFailover模塊。
if ( $master_state eq "dead" ) { $exit_code = MHA::MasterFailover::main(@ARGV); } elsif ( $master_state eq "alive" ) { $exit_code = MHA::MasterRotate::main(@ARGV); } else { pod2usage(1); }
MasterMonitor.pm,MasterRotate.pm,MasterFailover.pm這三個模塊都是調(diào)用Config.pm模塊來讀取參數(shù)配置,所以我們只需要修改這幾個模塊即可。
為了不平的網(wǎng)絡(luò)環(huán)境,我在配置文件加了這三個配置項:
app_vip :主庫的VIP
netmask : VIP的網(wǎng)絡(luò)位
interface :VIP要綁定的網(wǎng)上
對應(yīng)調(diào)整的代碼如下:
Config.pm:
申明變量:
my @PARAM_ARRAY = qw/ hostname ip port ssh_host ssh_ip ssh_port ssh_connection_timeout ssh_options node_label candidate_master no_master ignore_fail skip_init_ssh_check skip_reset_slave user password repl_user repl_password disable_log_bin master_pid_file handle_raw_binlog ssh_user remote_workdir master_binlog_dir log_level manager_workdir manager_log check_repl_delay check_repl_filter latest_priority multi_tier_slave ping_interval ping_type secondary_check_script master_ip_failover_script master_ip_online_change_script shutdown_script report_script init_conf_load_script client_bindir client_libdir use_gtid_auto_pos app_vip netmask interface/;
給變量賦值:
$value{app_vip} = $param_arg->{app_vip}; if ( !defined( $value{app_vip} ) ) { $value{app_vip} = $default->{app_vip}; } $value{netmask} = $param_arg->{netmask}; if ( !defined( $value{netmask} ) ) { $value{netmask} = $default->{netmask}; } $value{interface} = $param_arg->{interface}; if ( !defined( $value{interface} ) ) { $value{interface} = $default->{interface}; }
MasterMonitor.pm :
修改復(fù)制檢測時的命令:
"$current_master->{master_ip_failover_script} --command=status --ssh_user=$current_master->{ssh_user} --orig_master_host=$current_master->{hostname} --orig_master_ip=$current_master->{ip} --orig_master_port=$current_master->{port} --app_vip=$current_master->{app_vip} --netmask=$current_master->{netmask} --interface=$current_master->{interface}";
MasterMonitor.pm :
修改停原主庫寫入的命令:
"$orig_master->{master_ip_online_change_script} --command=stop --orig_master_host=$orig_master->{hostname} --orig_master_ip=$orig_master->{ip} --orig_master_port=$orig_master->{port} --orig_master_user=$orig_master->{escaped_user} --orig_master_password=$orig_master->{escaped_password} --new_master_host=$new_master->{hostname} --new_master_ip=$new_master->{ip} --new_master_port=$new_master->{port} --new_master_user=$new_master->{escaped_user} --new_master_password=$new_master->{escaped_password} --app_vip=$orig_master->{app_vip} --netmask=$orig_master->{netmask} --interface=$orig_master->{interface}";
修改允許在新主庫寫入的命令:
"$new_master->{master_ip_online_change_script} --command=start --orig_master_host=$orig_master->{hostname} --orig_master_ip=$orig_master->{ip} --orig_master_port=$orig_master->{port} --orig_master_user=$orig_master->{escaped_user} --orig_master_password=$orig_master->{escaped_password} --new_master_host=$new_master->{hostname} --new_master_ip=$new_master->{ip} --new_master_port=$new_master->{port} --new_master_user=$new_master->{escaped_user} --new_master_password=$new_master->{escaped_password} --app_vip=$orig_master->{app_vip} --netmask=$orig_master->{netmask} --interface=$orig_master->{interface}";
MasterFailover.pm:
修改禁用原從庫的vip命令:
"$dead_master->{master_ip_failover_script} --orig_master_host=$dead_master->{hostname} --orig_master_ip=$dead_master->{ip} --orig_master_port=$dead_master->{port} --app_vip=$dead_master->{app_vip} --netmask=$dead_master ->{netmask} --interface=$dead_master->{interface}";
修改啟用原從庫vip的命令:
"$new_master->{master_ip_failover_script} --command=start --ssh_user=$new_master->{ssh_user} --orig_master_host=$dead_master->{hostname} --orig_master_ip=$dead_master->{ip} --orig_master_port=$dead_master->{port} --new_m aster_host=$new_master->{hostname} --new_master_ip=$new_master->{ip} --new_master_port=$new_master->{port} --new_master_user=$new_master->{escaped_user} --new_master_password=$new_master->{escaped_password} --app_vip=$de ad_master->{app_vip} --netmask=$dead_master->{netmask} --interface=$dead_master->{interface}";