MHA 代码解析(online swtich+master is alive 模式)

MHA · ruyi · 于 1年前发布 · 1190 次阅读

通过MHA在线切换代码流程分析,我们了解到MHA在online change时会执行以下大致步骤:

  • 首先获得主备库信息
  • 其次检查切换条件
  • 选择新主库进行切换(因为我们MHA是二次开发过的,所有直接会激活主库,然后切换主库域名到新主库)
  • 切换到新主库后,才会把其他slave接到新主库,每个备库一个子进程
  • 等待所有子进程结束,最后把原主库接到新主库。
  • PS:这里面就意味着备库如果有延迟的话子进程会等延迟结束后才会接到新主库,不影响切换到主库,如果是延迟备库的话,有可能会一直等了,虽然主库切过去了,但是延迟备库切换会有问题,包括后续原主库也就切不成备库了。

代码流程如下(代码只提取了核心部分):

1.这一段基本就是获得主备库和信息,检查切换条件,条件不符直接退出

masterha_master_switch---->do_master_online_switch----->identify_orig_master(获得原主库)-----------$_server_manager->get_alive_servers();【获得@servers,@dead_servers,@alive_servers,@alive_slaves的基础信息】
                                                                                                   
if ( $#dead_servers >= 0 )【如果有dead_servers那么停止online switch】
					                                                         
$_server_manager->check_repl_priv()[复制权限验证]
												   
是否进行交互,询问是否进行flush tables.
默认不交互,那么默认是$orig_master->flush_tables();【在原主库进行flush tables】
												    
get_monitor_advisory_lock+get_failover_advisory_lock[查看是否有开启了mha或者在slave上failover,如果是则退出]
												    
check_replication_health【check 同步是否正常,不正常就退出】
												    
return orig_master【返回原主库】

2.这一段基本就是在选择新主库,没有能成为new master的条件也会退出

identify_new_master($orig_master)-----------select_new_master( $g_new_master_host,$g_new_master_port, 0 )【根据参数选择new master】
$_server_manager->is_target_bad_for_new_master($new_master)[判断选择的new_master是否能master,如果不能成为master 退出]------[1:no_master=1 2binlog没有开启 3mysql版本最低 4延迟比较大(如果有check_replication_delay参数) 5dead servers]$_->{no_master} >= 1|| $_->{log_bin} eq '0'|| $_->{oldest_major_version} eq '0' || ( $latest_slave && ( $check_replication_delay&& $self->check_slave_delay( $_, $latest_slave ) >= 1 )
                                                                                                    
if ( $orig_master->{check_repl_filter} ) {check_filter( $orig_master, $new_master );}[check同步的过滤是否一样。如果不一样则退出]
												    
return $new_master;【返回new master】
						        
--check_only 【如果是 直接exit 0】
                                                        
reject_update[这个是不让ori master update]--->master_ip_online_change_script[if exits]  (--command=stop)

3.这里开始切换了,激活新主库,并把域名切过去

switch_master[切换到new master]------------>switch_master_internal [让new master同步到最新位置,同时返回new master的binlog] 底层sql:SELECT MASTER_POS_WAIT(?,?,0) AS Result															
							                                            master_ip_online_change_script(--command=start  )[让new master 可以写]
							                                            disable_read_only[new master禁用read_only,如果new master开启了read_only]
												     return new master的binlog位置

4.主库切好后才开始将新其他备库连接到新主库

switch_slaves------------------------------>switch_slaves_internal[并发处理所有的slave]-----next if ( $target->{id} eq $new_master->{id} );[除new master其余的原slave,都运行下面的函数]
$target->master_pos_wait($orig_master_log_file, $orig_master_log_pos, $pplog);[等待当前备库同步到原主库的binlog的位置]
$_server_manager->change_master_and_start_slave($target, $new_master, $master_log_file, $master_log_pos, $pplog);[在备库上change master到new master的位置上]

5.等待其他所有备库都切换完后,切换原主库到备库

$pm->wait_all_children; [等待上面的并发线程 全部运行完]
orig_master->unlock_tables()[这个是是否原主库的锁]
if (orig_master_is_new_slave=1[是否把原主库设置为new master的备库]) change_master_and_start_slave( $orig_master, $new_master, $master_log_file, $master_log_pos)
new master是否reset slave all(是由$new_master->{skip_reset_slave}控制)

如果没有error,到此online切换全部结束。

本文由 ruyi 创作,采用 知识共享署名 3.0 中国大陆许可协议 进行许可。 可自由转载、引用,但需署名作者且注明文章出处。


本帖已经被管理员设置为: 精华帖 !
共收到 0 条回复 MHA 代码解析
没有找到数据。
回复本帖 (需要登录)