*********************************** 监控主函数,若有异常,则返回异常信息 ( $exit_code, $dead_master, $ssh_reachable )
# interactive 默认为0,必须在启动时显式指定
my ( $exit_code, $dead_master, $ssh_reachable ) = MHA::MasterMonitor::main("--interactive=0",@ARGV );
MHA::MasterMonitor::main{
while (1) {
========== 检测直到MW挂了
my ( $exit_code, $dead_master, $ssh_reachable ) = wait_until_master_is_dead();
wait_until_master_is_dead->wait_until_master_is_unreachable
MHA::ManagerUtil::check_node_version 检查node的mysql版本, Carp::croak
MHA::NodeUtil::check_manager_version 检查manager 版本, Carp::croak
MHA::NodeUtil::create_dir_if($g_workdir)
MHA::ServerManager::connect_all_and_read_server_status 获取所有server状态
MHA::Server::connect_and_get_status
contain: master status, slave status, relay info
Carp::croak 几种情况
获取不到relay信息
5.6及以上版本从表 mysql.slave_relay_log_info 中
[5.1.0--5.6)版本从 global.relay_log_info_file文件中
5.1.0版本之前从 relay-log.info文件中
Salve 没有master信息
slave 状态异常:既不是master,也不是slave
Parallel::ForkManager 方式,每个server一个fork
MHA::ServerManager::init_servers 重新初始化server状态
dead server, alive server, alive slave, failed slave, unmanager slave
MHA::ServerManager::validate_current_master 验证当前master状态:是否有2个master?是否含有slave
++ babaoqi 发送告警信息
MHA::ServerManager::validate_slaves
# Check the following
# 1. All slaves are read_only (INFO)
# 2. All slaves see the same master ip/port (ERROR)
# 3. All slaves set relay_log_purge=0 (WARN)
# 4.All slaves have same replicationfilter rules with a master (ERROR)
++ babaoqi 发送告警信息
MHA::ServerManager::get_bad_candidate_masters 获取alive server中不能成为master的server
# The following servers can not be master:
# - dead servers
# - Set no_master in conf files (i.e. DR servers)
# - log_bin is disabled
# - Major version is not the oldest
# - too much replication delay
++ babaoqi 发送告警信息
MHA::ServerManager->Server::check_repl_priv 检查同步帐号权限
++ babaoqi 发送告警信息
MHA::SSHCheck::do_ssh_connection_check 检查所有server(node、manager)间的ssh连接
ssh SSH_OPT_CHECK -p port user@ip1 "ssh SSH_OPT_CHECK -p port user@ip2 exit ";
++ babaoqi 发送告警信息
MHA::HealthCheck->wait_until_unreachable(); 检查master连接,若失败最多尝试3次ssh SSH_OPT_CHECK -p port user@ip1 "ssh SSH_OPT_CHECK -p port user@ip2 exit ";
++ babaoqi 发送告警信息
++ babaoqi 发送告警信息
========== 对dead server的处理
$exit_code == $MHA::ManagerConst::MASTER_DEAD_RC ? "Master dead" : "Not master dead" );
# 启动时指定check模式
if ($g_check_only) { finalize(); }
# retry
if ( $exit_code && $exit_code == $RETRY ) { prepare_for_retry(); }
else {
# 异常返回值
if ( $exit_code && $exit_code != $MHA::ManagerConst::MASTER_DEAD_RC ) { finalize_on_error(); }
# 仅仅是monitor(如何配置?设置相应的处理脚本)
elsif ($g_monitor_only) { finalize(); }
return ( $exit_code, $dead_master, $ssh_reachable );
}
}
}
***********************************Master fail 处理
$exit_code = MHA::MasterFailover::main(
"--master_state=dead",
"--interactive=0",
"--dead_master_host=$dead_master->{hostname}",
"--dead_master_ip=$dead_master->{ip}",
"--dead_master_port=$dead_master->{port}",
"--ssh_reachable=$ssh_reachable",
@ARGV
);
MHA::MasterFailover::main{
do_master_failover
# 检测dead master
$dead_master = check_settings( \@servers_config );
# 将dead master强制关机,防止脑裂?
force_shutdown($dead_master);
# 选取最新的slave
check_set_latest_slaves();
# 保存dead master的binlog。所有?未同步到slave的?
save_master_binlog($dead_master);
# 获取最新的slave,并设为new master
my $latest_base_slave = find_latest_base_slave($dead_master);
$new_master = select_new_master( $dead_master, $latest_base_slave );
# 将所有slave挂在new master下面
my ( $master_log_file, $master_log_pos ) = recover_master( $dead_master, $new_master, $latest_base_slave );
$new_master->{activated} = 1;
$error_code = recover_slaves($dead_master,$new_master, $latest_base_slave, $master_log_file, $master_log_pos);
# 根据配置remove_dead_master_conf决定是否进行清除master_default.cnf中dead master的信息
if ($g_remove_dead_master_conf && $error_code == 0) { MHA::Config::delete_block_and_save($g_config_file, $dead_master->{id}, $log); }
# 清理
cleanup();
# 释放连接占用的锁
SELECT RELEASE_LOCK('MHA_Master_High_Availability_Failover') As Value // 默认timeout=1
# 释放连接
# 发送报告
send_report( $dead_master, $new_master ); // report_script 配置的脚本
# report_script --orig_master_host=$dead_master{host} --new_master_host=$new_master{host} --new_slave_hosts=new_slaves --conf=$config_file --subject=mail_subject --body=mail_body
-- new_slaves:所有alive slave的host使用逗号拼接
}