mha高可用master failover数据补齐过程--源码级别
1.master failover not gtid
传统方式复制master failover图

具体过程
Phase 1: Configuration Check Phase 1.init_config(): # 初始化配置 2.MHA::ServerManager::init_binlog_server: # 初始化binlog server 3.check_settings() a. check_node_version(): # 查看MHA的版本 b. connect_all_and_read_server_status(): # 检测确认各个Node节点MySQL是否可以连接 c. get_dead_servers(),get_alive_servers(),get_alive_slaves():# 再次检测一次node节点的状态 d. print_dead_servers(): # 是否挂掉的master是否是当前的master e. MHA::DBHelper::check_connection_fast_util : # 快速判断dead server,是否真的挂了,如果ping_type=insert,不会double check f. MHA::NodeUtil::drop_file_if($_failover_error_file|$_failover_complete_file): # 检测上次的failover文件 g. 如果上次failover的时间在8小时以内,那么这次就不会failover,除非配置了额外的参数 h. start_sql_threads_if(): # 查看所有slave的Slave_SQL_Running是否为Yes,若不是则启动SQL thread 4.is_gtid_auto_pos_enabled(): # 判断是否是GTID模式 Phase 2: Dead Master Shutdown Phase.. 1.force_shutdown($dead_master): a.stop_io_thread(): # stop所有slave的IO_thread b.force_shutdown_internal($dead_master): b_1. master_ip_failover_script: # 如果有这个脚本,则执行里面的逻辑(比如:切换vip) b_2. shutdown_script:# 如果有这个脚本,则执行里面的逻辑(比如:Power off 服务器) Phase 3: Master Recovery Phase.. Phase 3.1: Getting Latest Slaves Phase.. * check_set_latest_slaves() a. read_slave_status(): # 获取所有show slave status 信息 b. identify_latest_slaves(): # 找到最新的slave是哪个 c. identify_oldest_slaves(): # 找到最老的slave是哪个 Phase 3.2: Saving Dead Master’s Binlog Phase.. * save_master_binlog($dead_master); -> 如果dead master可以ssh,那么 b_1_1. save_master_binlog_internal:# 用node节点save_binary_logs脚本拷贝相应binlog到manager diff_binary_log # 生产差异binlog日志 b_1_2. file_copy: # 将差异binlog拷贝到manager节点的 manager_workdir目录下 -> 如果dead master不可以ssh b_1_3. # 那么差异日志就会丢失 Phase 3.3: Determining New Master Phase.. b. 如果GTID auto_pos没有打开,调用find_latest_base_slave() b_1. find_latest_base_slave_internal: # 寻找拥有所有relay-log的最新slave,如果没有,则failover失败 b_1_1. find_slave_with_all_relay_logs: b_1_1_1. apply_diff_relay_logs: # 查看最新的slave是否有其他slave缺失的relay-log c. select_new_master: # 选举new master c_1. MHA::ServerManager::select_new_master: #If preferred node is specified, one of active preferred nodes will be new master. #If the latest server behinds too much (i.e. stopping sql thread for online backups), we should not use it as a new master, but we should fetch relay log there #Even though preferred master is configured, it does not become a master if it's far behind get_candidate_masters(): # 获取配置中候选节点 get_bad_candidate_masters(): # 以下条件不能成为候选master # dead server # no_master >= 1 # log_bin=0 # oldest_major_version=0 # check_slave_delay: # 检查是否延迟非常厉害(可以通过设置no_check_delay忽略) {Exec_Master_Log_Pos} + 100000000 # 只要binlog position不超过100000000 就行 选举流程: 先看candidate_master,然后找 latest slave, 然后再随机挑选 Phase 3.3(3.4): New Master Diff Log Generation Phase.. * recover_master_internal recover_relay_logs: # 判断new master是否为最新的slave,如果不是,则生产差异relay logs,并发送给新master recover_master_internal: # 将之前生产的dead master上的binlog传送给new master Phase 3.4: Master Log Apply Phase.. * apply_diff: a. wait_until_relay_log_applied: # 直到new master完成所有relay log,否则一直等待 b. 判断Exec_Master_Log_Pos == Read_Master_Log_Pos, # 如果不等,那么生产差异日志: save_binary_logs --command=save c. apply_diff_relay_logs --command=apply:# 对new master进行恢复 c_1. exec_diff:Exec_Master_Log_Pos和Read_Master_Log_Pos的差异日志 # 这是在应用new master自己还未执行的relay log c_2. read_diff:new master与lastest slave的relay log的差异日志 # 这是应用拥有最多dead master的slave的relay log, 因为new master不一定是拥有dead master最多的数据。 c_3. binlog_diff:lastest slave与daed master之间的binlog差异日志 # * 如果设置了master_ip_failover_script脚本,那么会执行这里面的脚本(一般用来漂移vip) * disable_read_only(): 允许new master可写 Phase 4: Slaves Recovery Phase.. # recover_slaves_internal Phase 4.1: Starting Parallel Slave Diff Log Generation Phase.. recover_all_slaves_relay_logs: # 生成Slave与New Slave之间的差异日志,并将该日志拷贝到各Slave的工作目录下 Phase 4.2: Starting Parallel Slave Log Apply Phase.. * recover_slave: # 对每个slave进行恢复,跟以上Phase 3.4: Master Log Apply Phase中的 apply_diff一样 * change_master_and_start_slave:# 重新指向到new master,并且start slave Phase 5: New master cleanup phase.. # reset_slave_on_new_master 在new master上执行reset slave all;
总结:
生成差异binlog: 如果dead master可以ssh: 传统方式复制通过node节点上的save_binary_logs脚本从dead master上保存binlog,通过生成差异binlog日志,将差异binlog拷贝到manager节点的 manager_workdir目录下 如果dead master不可以ssh 那么差异日志就会丢失,也就是会丢失数据。 选主: 以下条件不能成为候选master # dead server # no_master >= 1 # log_bin=0 # oldest_major_version=0 # check_slave_delay 生成差异relay log: 判断new master是否为最新的slave,如果不是,则生产差异relay logs,并发送给新master 2.将之前生产的dead master上的binlog传送给new master
pass
2.master failover gtid
gtid复制方式 mha failover 流程图
具体过程
Phase 1: Configuration Check Phase 1.init_config(): # 初始化配置 2.MHA::ServerManager::init_binlog_server: # 初始化binlog server 3.check_settings() a. check_node_version(): # 查看MHA的版本 b. connect_all_and_read_server_status(): # 检测确认各个Node节点MySQL是否可以连接 c. get_dead_servers(),get_alive_servers(),get_alive_slaves():# 再次检测一次node节点的状态 d. print_dead_servers(): # 是否挂掉的master是否是当前的master e. MHA::DBHelper::check_connection_fast_util : # 快速判断dead server,是否真的挂了,如果ping_type=insert,不会double check f. MHA::NodeUtil::drop_file_if($_failover_error_file|$_failover_complete_file): # 检测上次的failover文件 g. 如果上次failover的时间在8小时以内,那么这次就不会failover,除非配置了额外的参数 h. start_sql_threads_if(): # 查看所有slave的Slave_SQL_Running是否为Yes,若不是则启动SQL thread 4.is_gtid_auto_pos_enabled(): # 判断是否是GTID模式 Phase 2: Dead Master Shutdown Phase.. 1.force_shutdown($dead_master): a.stop_io_thread(): # stop所有slave的IO_thread b.force_shutdown_internal($dead_master): b_1. master_ip_failover_script: # 如果有这个脚本,则执行里面的逻辑(比如:切换vip) b_2. shutdown_script:# 如果有这个脚本,则执行里面的逻辑(比如:Power off 服务器) Phase 3: Master Recovery Phase.. Phase 3.1: Getting Latest Slaves Phase.. * check_set_latest_slaves() a. read_slave_status(): # 获取所有show slave status 信息 b. identify_latest_slaves(): # 找到最新的slave是哪个 c. identify_oldest_slaves(): # 找到最老的slave是哪个 Phase 3.2: Saving Dead Master’s Binlog Phase.. * save_master_binlog($dead_master); -> 如果dead master可以ssh,那么 b_1_1. save_master_binlog_internal:# 用node节点save_binary_logs脚本拷贝相应binlog到manager diff_binary_log # 生产差异binlog日志 b_1_2. file_copy: # 将差异binlog拷贝到manager节点的 manager_workdir目录下 -> 如果dead master不可以ssh b_1_3. # 那么差异日志就会丢失 Phase 3.3: Determining New Master Phase.. b. 如果GTID auto_pos没有打开,调用find_latest_base_slave() b_1. find_latest_base_slave_internal: # 寻找拥有所有relay-log的最新slave,如果没有,则failover失败 b_1_1. find_slave_with_all_relay_logs: b_1_1_1. apply_diff_relay_logs: # 查看最新的slave是否有其他slave缺失的relay-log c. select_new_master: # 选举new master c_1. MHA::ServerManager::select_new_master: #If preferred node is specified, one of active preferred nodes will be new master. #If the latest server behinds too much (i.e. stopping sql thread for online backups), we should not use it as a new master, but we should fetch relay log there #Even though preferred master is configured, it does not become a master if it's far behind get_candidate_masters(): # 获取配置中候选节点 get_bad_candidate_masters(): # 以下条件不能成为候选master # dead server # no_master >= 1 # log_bin=0 # oldest_major_version=0 # check_slave_delay: # 检查是否延迟非常厉害(可以通过设置no_check_delay忽略) {Exec_Master_Log_Pos} + 100000000 # 只要binlog position不超过100000000 就行 选举流程: 先看candidate_master,然后找 latest slave, 然后再随机挑选 Phase 3.4 New Master Diff Log Generation Phase.. * recover_master_gtid_internal: wait_until_relay_log_applied: # 候选master等待所有relay-log都应用完 # 如果候选master不是最新的slave: $latest_slave->wait_until_relay_log_applied($log): # 最新的slave应用完所有的relay-log change_master_and_start_slave : # 让候选master同步到latest master,追上latest slave # 获取候选master此时此刻的日志信息,以便后面切换 # 如果候选master是最新的slave: # 获取候选master此时此刻的日志信息,以便后面切换 save_from_binlog_server: # 如果配置了binlog server,那么在binlogsever 能连的情况下,将binlog 拷贝到Manager,并生成差异日志diff_binlog(save_binary_logs --command=save) apply_binlog_to_master: Applying differential binlog:# 应用差异的binlog到new master Phase 4: Slaves Recovery Phase.. Phase 4.1: Starting Slaves in parallel.. * recover_slaves_gtid_internal: change_master_and_start_slave: # 因为master已经恢复,那么slave直接change master auto_pos=1 的模式就可以恢复 gtid_wait:# 用此等待同步全部追上 Phase 5: New master cleanup phase.. # reset_slave_on_new_master 在new master上执行reset slave all;
pass
pass
上帝说要有光,于是便有了光;上帝说要有女人,于是便有了女人!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· AI与.NET技术实操系列(六):基于图像分类模型对图像进行分类