MHA:源码阅读笔记

master_manager 命令

*********************************** 监控主函数,若有异常,则返回异常信息 ( $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次
                     ++ 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使用逗号拼接
}










请使用浏览器的分享功能分享到微信等