mysql 源码 库函数_【MySQL】MHA源代码之主库选取(二)
一
、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源代码之主库选取(二)相关推荐
- mysql源码包结构,mysql源码结构介绍
mysql源码非常庞大,直接去看肯定毫无头绪.至少需要知道哪个目录是做什么的,才能有一定的条理.现在对mysql的源码结构做初步介绍 目录结构 ==来自622463 MySQL运维内参:MySQL.G ...
- ubuntu 安装mysql 源码,命令ubuntu上用源代码安装mysql的详细操作说明
文档说明 上次写了一篇linu x下架设完美私服的文章提到了我想用mysq l架设的想法.这次的安装说明就是为其做准备的.希望大家多多的支持如果有疑问请大家联系我我将想办法为大家解决.我的空间 ...
- 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_ ...
- bootstrap mysql源码_Django+Bootstrap+Mysql 搭建个人博客 (六)
6.1.comments插件 (1)安装 pip install django-contrib-comments (02)settings INSTALLED_APPS =['django.contr ...
- mysql 源码设计,java+mysql大学网络社区平台设计+源代码
摘要如今,信息管理与信息系统的网络平台上,更多的都是一些静态信息的介绍,缺乏老师与老师之间, 老师与同学之间信息的交流的功能. 因此, 需要建立一个从 Web 1.0转换到 Web 2.0 的, 能够 ...
- MySQL源码学习:MySQL中禁止跨库访问的实现
摘要: 先说一下这里"跨库"的意思:当前use的是db1, 仍可以使用select * from db2.table1来访问table1表. 这样使得我们需要访问同一个MySQL ...
- ubuntu 环境下调试mysql源码_【转】Ubuntu 16.04下 Mysql 5.7.17源码编译与安装
Ubuntu 16.04下 Mysql5.7.17源码编译与安装 系统环境 一. 系统安装条件 1.cmake MySQL使用cmake跨平台工具预编译源码,用于设置mysql的编译参数. sudo ...
- MySQL 源码分析 v2.0
第一节 mysql编译 (一).参考 https://blog.jcole.us/innodb/ https://www.cnblogs.com/zengkefu/p/5674503.html htt ...
- Mysql源码编译和调试debug
下载源码 直接从github 上下载了源码.git 地址:https://github.com/mysql/mysql-server 下载路径如:/work/mysql-server 编译 依赖 ma ...
最新文章
- 优化C代码常用的几招
- 同一页面实现多个Tab选项卡功能
- Java中代码块和继承
- 月薪五万挖过来的高管第二天就离职了,为何公司总留不住优秀人才?
- 【原创】大叔问题定位分享(4)Kafka集群broker节点从zookeeper上消失
- 矩阵分解——三角分解(Cholesky 分解)
- bzoj 1670: [Usaco2006 Oct]Building the Moat护城河的挖掘(凸包)
- 关于web页面打开空白的情况
- 每日一技|巧用 Telnet 调试 Dubbo 服务
- python尺与米的转换_在线长度换算-公里换算-米换算-纳米换算-长度单位在线换算工具...
- 计算机文件只读模式,电脑文件只读模式如何修改 – 手机爱问
- html360全景图原理,HTML5中Canvas如何实现360度全景图
- vue全家桶都有哪些
- tushare pro 版本获取股票历史数据
- 使用ArchR分析单细胞ATAC-seq数据(第十二章)
- 1.3读论文笔记:M. Raissi a等人的Physics-informed neural networks:A deep learning framework for solving forw..
- 12月编程语言排行榜,java跌至低点,低代码发展迅猛
- 如何获取所有股票代码
- 防伪码查询溯源小程序开发
- C#Object类型
热门文章
- python画饼图-python matplotlib画饼图
- python程序员薪资-python工资高还是java?
- python介绍和用途-python中模块的介绍与使用
- python安装教程mac-Mac 上安装python3——手把手教程
- python与excel的差别-python数据分析相对于bi和excel的优势是什么?
- 学python可以做什么职业好-学了那么多年python到底可以找什么工作?
- python装饰器函数-python函数装饰器之带参数的函数和带参数的装饰器用法示例
- python官网 中文版 新闻-用python看新闻
- python编程小学生学好吗-小学生都开始学的Python编程到底是什么?
- python使用open打开文件时显示文件不存在-Python打开文件open()的注意事项