、MHA

选举主库所维护的数组

在讲MHA选择

master的代码中,我们必须把维护的四个数组的来龙去脉讲清楚

(1)

Alive_slaves

数组

:

server不是

master,且从库正常,

latest数组中的

server有足够的中继日志恢复这个落后的从库

(追上主库

),则放入这个

Alive_slaves的数组中

(此段代码在

ServerManager.pm:

init_servers函数

)

if ( $server->{dead} ) {

$self->add_dead_server($server);

}

elsif ( $server->{unmanaged} ) {

$self->add_unmanaged_slave($server);

}

#不是dead或者unmanaged就加入alive_server数组,如果show slave status 不是返回0E0,且这个server不是原来的主库,并且sql线程无误且可以用中继日志来恢复,就加入alive_slave数据,否则加入failed——slave数组

else {

$self->add_alive_server($server);

if ( $server->{not_slave} eq '0' && !$server->{orig_master} ) {

if ( !$server->is_sql_thread_error() && !$server->{lack_relay_log} ) {

$self->add_alive_slave($server);

}

else {

$self->add_failed_slave($server);

}

}

}

(2)Latest

数组

alive_slaves数组中选取

relaylog最新的

server,这个数组如果有多个

server,则

server的

Read_master_log_pos,master_log_file一定相等(此段代码在

ServerManager.pm:

identify_latest_slaves函数)

my @slaves = $self->get_alive_slaves();

my @latest = ();

foreach (@slaves) {

my $a = $latest[0]{Master_Log_File};

my $b = $latest[0]{Read_Master_Log_Pos};

if (

#find_oldest=0,即我们取的最全relaylog的slave,至于这里为什么是数组,是因为有最新的relaylog的不只有一个,可能有多个((即数组里边边的slave,具有一样的Read_Master_Log_     Pos位置))

!$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]{Read_Master_Log_Pos} )

)

)

{

@latest = ();

push( @latest, $_ );

}

(3)Perf

数组

这个无需多解释,就是MHA配置文件中配置了

candidate_master的值,这个可以大于

1哦

(4)Bad

数组:

(

代码见:

ServerManager.pm:get_bad_candidate_masters)

1)

检测有故障的server

2)

MHA

配置文件设置了

no_master

server

3)log_bin

没有打开的server

4)

版本不兼容的server

(高版本复制到低版本是没问题的,但是如果低版本的选为为主库,嘿嘿)

5)

复制落后太多的server

、MHA

主库的选举

(1)

指定主库切换的,优先级最高(通常这是在手动切换)

(2)

如果server

latest

数组中,且在

perf

数组中,则优先返回

(3)

如果server

alive_servers

数组中,且在

perf

数组中,则优先返回

(4)

如果server

lastest

中,则优先返回

(5)

如果server

alive_servers

中,则返回

(6)

否则选举失败

这里优先级为1->6,具体实现在

(ServerManager.pm: select_new_master)

sub select_new_master {

my $self                    = shift;

my $prio_new_master_host    = shift;

my $prio_new_master_port    = shift;

my $check_replication_delay = shift;

$check_replication_delay = 1 if ( !defined($check_replication_delay) );

my $log    = $self->{logger};

my @latest = $self->get_latest_slaves();

my @slaves = $self->get_alive_slaves();

my @pref = $self->get_candidate_masters();

my @bad =

$self->get_bad_candidate_masters( $latest[0], $check_replication_delay );

#切换指定了master,即优先级最高的

if ( $prio_new_master_host && $prio_new_master_port ) {

my $new_master =

$self->get_alive_server_by_hostport( $prio_new_master_host,

$prio_new_master_port );

if ($new_master) {

my $a = $self->get_server_from_by_id( \@bad, $new_master->{id} );

unless ($a) {

$log->info("$prio_new_master_host can be new master.");

return $new_master;

}

else {

$log->error("$prio_new_master_host is bad as a new master!");

return;

}

}

else {

$log->error("$prio_new_master_host is not alive!");

return;

}

}

$log->info("Searching new master from slaves..");

$log->info(" Candidate masters from the configuration file:");

$self->print_servers( \@pref );

$log->info(" Non-candidate masters:");

$self->print_servers( \@bad );

#如果perf(candidate_master没设置)以及没有不符合(主从延迟,版本等)的slave,并且lastest[0]设置有优先级的话,就返回

return $latest[0]

if ( $#pref {latest_priority} );

#如果设置了优先级,则从lastest数组中选择是canidate_master的,有就返回(隐含lastest[0]优先,如果lastest[0]同时是canidate_master,那肯定是优先返回的)

#latest_priority默认设置为1

if ( $latest[0]->{latest_priority} ) {

$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 );

}

#new master is not latest

#这里选择的是candidate_master,单不是latest数组中的master

$log->info(" Searching from all candidate_master slaves..")

if ( $#pref >= 0 );

foreach my $s (@slaves) {

foreach my $p (@pref) {

if ( $s->{id} eq $p->{id} ) {

my $a = $self->get_server_from_by_id( \@bad, $p->{id} );

return $s unless ($a);

}

}

}

$log->info("  Not found.") if ( $#pref >= 0 );

#其次是优先在lastest数组中,但不在candidate_master中的

if ( $latest[0]->{latest_priority} ) {

$log->info(

" Searching from all slaves which have received the latest relay log events.."

);

foreach my $h (@latest) {

my $a = $self->get_server_from_by_id( \@bad, $h->{id} );

return $h unless ($a);

}

$log->info("  Not found.");

}

# none of latest servers can not be a master

$log->info(" Searching from all slaves..");

foreach my $s (@slaves) {

my $a = $self->get_server_from_by_id( \@bad, $s->{id} );

return $s unless ($a);

}

$log->info("  Not found.");

return;

}

mysql 源码 库函数_【MySQL】MHA源代码之主库选取(二)相关推荐

  1. mysql源码包结构,mysql源码结构介绍

    mysql源码非常庞大,直接去看肯定毫无头绪.至少需要知道哪个目录是做什么的,才能有一定的条理.现在对mysql的源码结构做初步介绍 目录结构 ==来自622463 MySQL运维内参:MySQL.G ...

  2. ubuntu 安装mysql 源码,命令ubuntu上用源代码安装mysql的详细操作说明

    文档说明 上次写了一篇linu x下架设完美私服的文章提到了我想用mysq l架设的想法.这次的安装说明就是为其做准备的.希望大家多多的支持如果有疑问请大家联系我我将想办法为大家解决.我的空间 ...

  3. python mysql源码安装_源码包安装(Python mysql redis)

    3.1解压及制作软连接 tar xf mysql-5.7.20-linux-glibc2.12-x86_64.tar.gz ln-s mysql-5.7.20-linux-glibc2.12-x86_ ...

  4. bootstrap mysql源码_Django+Bootstrap+Mysql 搭建个人博客 (六)

    6.1.comments插件 (1)安装 pip install django-contrib-comments (02)settings INSTALLED_APPS =['django.contr ...

  5. mysql 源码设计,java+mysql大学网络社区平台设计+源代码

    摘要如今,信息管理与信息系统的网络平台上,更多的都是一些静态信息的介绍,缺乏老师与老师之间, 老师与同学之间信息的交流的功能. 因此, 需要建立一个从 Web 1.0转换到 Web 2.0 的, 能够 ...

  6. MySQL源码学习:MySQL中禁止跨库访问的实现

    摘要:  先说一下这里"跨库"的意思:当前use的是db1, 仍可以使用select * from db2.table1来访问table1表. 这样使得我们需要访问同一个MySQL ...

  7. ubuntu 环境下调试mysql源码_【转】Ubuntu 16.04下 Mysql 5.7.17源码编译与安装

    Ubuntu 16.04下 Mysql5.7.17源码编译与安装 系统环境 一. 系统安装条件 1.cmake MySQL使用cmake跨平台工具预编译源码,用于设置mysql的编译参数. sudo ...

  8. MySQL 源码分析 v2.0

    第一节 mysql编译 (一).参考 https://blog.jcole.us/innodb/ https://www.cnblogs.com/zengkefu/p/5674503.html htt ...

  9. Mysql源码编译和调试debug

    下载源码 直接从github 上下载了源码.git 地址:https://github.com/mysql/mysql-server 下载路径如:/work/mysql-server 编译 依赖 ma ...

最新文章

  1. 优化C代码常用的几招
  2. 同一页面实现多个Tab选项卡功能
  3. Java中代码块和继承
  4. 月薪五万挖过来的高管第二天就离职了,为何公司总留不住优秀人才?
  5. 【原创】大叔问题定位分享(4)Kafka集群broker节点从zookeeper上消失
  6. 矩阵分解——三角分解(Cholesky 分解)
  7. bzoj 1670: [Usaco2006 Oct]Building the Moat护城河的挖掘(凸包)
  8. 关于web页面打开空白的情况
  9. 每日一技|巧用 Telnet 调试 Dubbo 服务
  10. python尺与米的转换_在线长度换算-公里换算-米换算-纳米换算-长度单位在线换算工具...
  11. 计算机文件只读模式,电脑文件只读模式如何修改 – 手机爱问
  12. html360全景图原理,HTML5中Canvas如何实现360度全景图
  13. vue全家桶都有哪些
  14. tushare pro 版本获取股票历史数据
  15. 使用ArchR分析单细胞ATAC-seq数据(第十二章)
  16. 1.3读论文笔记:M. Raissi a等人的Physics-informed neural networks:A deep learning framework for solving forw..
  17. 12月编程语言排行榜,java跌至低点,低代码发展迅猛
  18. 如何获取所有股票代码
  19. 防伪码查询溯源小程序开发
  20. C#Object类型

热门文章

  1. python画饼图-python matplotlib画饼图
  2. python程序员薪资-python工资高还是java?
  3. python介绍和用途-python中模块的介绍与使用
  4. python安装教程mac-Mac 上安装python3——手把手教程
  5. python与excel的差别-python数据分析相对于bi和excel的优势是什么?
  6. 学python可以做什么职业好-学了那么多年python到底可以找什么工作?
  7. python装饰器函数-python函数装饰器之带参数的函数和带参数的装饰器用法示例
  8. python官网 中文版 新闻-用python看新闻
  9. python编程小学生学好吗-小学生都开始学的Python编程到底是什么?
  10. python使用open打开文件时显示文件不存在-Python打开文件open()的注意事项