知数堂第5期MySQL实战班学员,第10期MySQL优化班学员,现任职助教。

MHA在选择新的主库之前,会先把活着的slave分为几个数组,分别为latest(最靠前的slave数组),pref(优先被选择为master的数组),bad(不会被选择成为master的slave),slaves(所有活着的slave数组)。然后进行5次选择,从上面的这些组当中挑选出新的master。

选择latest数组

foreach (@slaves) {
my $a = $latest[0]{Master_Log_File};
my $b = $latest[0]{Read_Master_Log_Pos};
if (
!$find_oldest
&& (
( !$a && !defined($b) )
|| ( $_->{Master_Log_File} gt $latest[0]{Master_Log_File} )
|| ( ( $_->{Master_Log_File} ge $latest[0]{Master_Log_File} )
&& $_->{Read_Master_Log_Pos} > $latest[0]www.wanmeiyuele.cn{Read_Master_Log_Pos} )
)
)
{
@latest = ();
push( @latest, $_ );
}
elsif (
$find_oldest
&& (
( !$a && !defined($b) )
|| ( $_->{Master_Log_File} lt $latest[0]{Master_Log_File} )
|| ( ( $_->{Master_Log_File} le $latest[0]{Master_Log_File} )
&& $_->{Read_Master_Log_Pos} < $latest[0]{Read_Master_Log_Pos} )
)
)
{
@latest = ();
push( @latest, $_ );
}
elsif ( ( $_->{Master_Log_File} eq $latest[0]{Master_Log_File} )
&& ( $_->{Read_Master_Log_Pos} == $latest[0]{Read_Master_Log_Pos} ) )
{
push( @latest, $_ );
}
}

上面代码主要的结构就是一个foreach循环,一个if判断。foreach循环处理所有的活着的slave。if判断这里有三个判断条件,主要根据Master_Log_File和Read_Master_Log_Pos的大小来判断。第一个和第二个分别为了找出最靠前和最靠后的slave的。如果满足条件,那么就清空latest数组,把符合条件的放入latest数组里面。第三个条件用于找出和latest数组里面Master_Log_File和Read_Master_Log_Pos一样的slave,并放入latest数组。这样所有的 最靠前的就都放入latest数组里面了。

选择pref数组

foreach (@servers) {
    next if ( $_->{dead} eq '1' );
    if ( $_->{candidate_master} >= 1 ) {
      push( @ret_servers, $_ );
    }
  }

循环处理所有的配置server,已经死了的slave跳过,有参数candidate_master=1的slave放入pref数组,会被优先推举为新的master。

选择bad数组

 foreach (@servers) {
    if (
         $_->{no_master} >= 1
      || $_->{log_bin}www.365soke.cn  eq '0'
      || $_->{oldest_major_version} eq '0'
      || (
        $latest_slave
        && ( $check_replication_delay
          && $self->check_slave_delay( $_, $latest_slave ) >= 1 )
      )
      )
    {
      push( @ret_servers, $_ );
    }
  }

也是循环处理所有的配置的server,满足下面三个条件之一就会被选择放入bad数组,也就说这些slave不会被推选为新的master。

  1. 添加了参数no_master=1

  2. 没有开启binlog

  3. 如果延迟太大,如何才算是复制延迟太大呢?

 ( $latest->{Master_Log_File} gt $target->{Relay_Master_Log_File} )
|| ( $latest->{Read_Master_Log_Pos} >
$target->{Exec_Master_Log_Pos} + 100000000 )

这里的latest就是上面选择出来最靠前的第一个latest slave,不过所有的latest都是一样的,所以选择哪一个用于比较都是没关系的。要么latest的master_log_file > 对比者的Relay_Master_Log_File。或者是两者相同,但是latest的Read_Master_Log_Pos > 对比者的Exec_Master_Log_Pos+1亿。如果设置了参数check_repl_delay=0,那就不会会检查复制延迟。

选择slaves数组

只要是活着的slave都会被放进slaves数组当中。

这里需要说明的是,一个slave可以放进多个数组当中。不是一个slave只能存放到一个数组当中。

第一次选择:

return $latest[0] if ( $#pref <www.feihuanyule.com  0 && $#bad < 0 && $latest[0]->{latest_priority} );

如果pref和bad数组当中slave的个数为0,则选择latest数组当中的第一个slave为master。

第二次选择:

$log->info(
" Searching from candidate_master slaves which have received the latest relay log events.."
) if ( $#pref >= 0 );
foreach my $h (@latest) {
foreach my $p (@pref) {
if ( $h->{id} eq $p->{id} ) {
return $h
if ( !$self->get\_server\_from\_by\_id( \@bad, $p->{id} ) );
}
}
}
$log->info(" Not found.") if ( $#pref >= 0 );

循环对比latest数组和perf数组的slave,如果存在相同的slave,并且这个slave不在bad数组当中,该slave会被推选为新的master。

第三次选择:

foreach my $s (@slaves) {
foreach my $p (@pref)www.hbs90.cn/ {
if ( $s->{id} eq $p->{id} ) {
my $a = $self->get_server_from_by_id( \@bad, $p->{id} );
return $s unless ($a);
}
}
}

循环对比slaves数组pref数组当中的slave,如果有一个slave相同并且不在bad数组当中,该就会成为新的master。

第四次选择:

foreach my $h (@latest) {
my $a = $self->get_server_from_by_id( @bad, $h->{id} );
return $h unless ($a);
}

循环latest数组,如果有循环到的slave不在bad数组当中,这个slave就会成为master。也就是说就算添加了candidate_master=1,该slave也不一定会成为主库。

第五次选择:

foreach my $s (@slaves)www.yibaoyule1.com/ {
my $a = $self->get_server_from_by_id( @bad, $s->{id} );
return $s unless (www.huayi1.cn/ $a);
}

从活着的slave当中进行循环,如果循环到的slave不在bad数组当中,那么这个slave就会成为主库。 如果进行了5次选择都找不到主库,那么主库选择失败,failover失败。

MHA选择主库源码解析的更多相关文章

  1. jQuery2.x源码解析(设计篇)

    jQuery2.x源码解析(构建篇) jQuery2.x源码解析(设计篇) jQuery2.x源码解析(回调篇) jQuery2.x源码解析(缓存篇) 这一篇笔者主要以设计的角度探索jQuery的源代 ...

  2. Python2 基本数据结构源码解析

    Python2 基本数据结构源码解析 Contents 0x00. Preface 0x01. PyObject 0x01. PyIntObject 0x02. PyFloatObject 0x04. ...

  3. EventBus源码解析 源码阅读记录

    EventBus源码阅读记录 repo地址: greenrobot/EventBus EventBus的构造 双重加锁的单例. static volatile EventBus defaultInst ...

  4. Java集合---Array类源码解析

    Java集合---Array类源码解析              ---转自:牛奶.不加糖 一.Arrays.sort()数组排序 Java Arrays中提供了对所有类型的排序.其中主要分为Prim ...

  5. 源码解析-Volley(转自codeKK)

    Volley 源码解析 本文为 Android 开源项目源码解析 中 Volley 部分项目地址:Volley,分析的版本:35ce778,Demo 地址:Volley Demo分析者:grumoon ...

  6. jQuery整体架构源码解析(转载)

    jQuery整体架构源码解析 最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性, ...

  7. JQuery源码解析(一)

    写在前面:本<JQuery源码解析>系列是基于一些前辈们的文章进行进一步的分析.细化.修改而写出来的,在这边感谢那些慷慨提供科普文档的技术大拿们. 要查阅JQ的源文件请下载开发版的JQ.j ...

  8. Java 集合系列16之 HashSet详细介绍(源码解析)和使用示例

    概要 这一章,我们对HashSet进行学习.我们先对HashSet有个整体认识,然后再学习它的源码,最后再通过实例来学会使用HashSet.内容包括:第1部分 HashSet介绍第2部分 HashSe ...

  9. 给jdk写注释系列之jdk1.6容器(12)-PriorityQueue源码解析

    PriorityQueue是一种什么样的容器呢?看过前面的几个jdk容器分析的话,看到Queue这个单词你一定会,哦~这是一种队列.是的,PriorityQueue是一种队列,但是它又是一种什么样的队 ...

随机推荐

  1. kaggle入门--泰坦尼克号之灾(手把手教你)

    作者:炼己者 具体操作请看这里-- https://www.jianshu.com/p/e79a8c41cb1a 大家也可以看PDF版,用jupyter notebook写的,视觉效果上感觉会更棒 链 ...

  2. uvaoj 489 - Hangman Judge(逻辑+写代码能力)

    https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  3. 180609-Spring之事件驱动机制的简单使用

    文章链接:https://liuyueyi.github.io/hexblog/hexblog/2018/06/09/180609-Spring之事件驱动机制的简单使用/ Spring之事件驱动机制的 ...

  4. Eclipse 常用快捷键 个性设置(Mac)

    推荐编程使用Mac 要是非要一个原因 那就是Apple工程师用Mac Google工程师也用Mac 1. 常用快捷键 Mac自带 Command + ←  跳到当前文本行头 Command + →  ...

  5. JSON.parse() 与 eval()

    JSON(JavaScript Object Notation)是一种轻量级的数据格式,采用完全独立于语言的文本格式,是理想的数据交换格式.同时,JSON是Javascript原生格式,这意味着在ja ...

  6. 我的linux操作习惯

    标签(空格分隔): ubuntu 最佳操作 用linux随时可能会有宕机的危险,谁知道我哪会神经病犯了呢.用deepin宕机的可能性会更高的,所以我才不得不安装一个windows做备份,然后把数据备份 ...

  7. Too many open files错误与解决方法

    致前辈:该问题的解决思路给了我很大的启发,文章作者Lis, Linux资深技术专家. 问题现象:这是一个基于Java的web应用系统,在后台添加数据时提示无法添加,于是登陆服务器查看Tomcat 日志 ...

  8. js经典试题之w3规范系列

    js经典试题之w3规范系列 1:w3c 制定的 javascript 标准事件模型的正确的顺序? 答案:事件捕获->事件处理->事件冒泡 解析:先事件捕获从windows > doc ...

  9. nginx 添加的配置信息

    使用logrotate管理Nginx日志配置如下: [root@vm-10-129-93-51 nginx]# vi /etc/logrotate.d/nginx /letv/log/nginx/*. ...

  10. rsync+inotify实现实时同步,自动触发同步文件

    本文参考来自:http://chocolee.blog.51cto.com/8158455/1400596 我的需求和他的略有不同,同时做了一下更改,如下: 需求:两台机器相互为主备,搭建相同的两个服 ...