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
上帝说要有光,于是便有了光;上帝说要有女人,于是便有了女人!