【MySQL】MHA部署与MasterFailover代码分析

官网:https://code.google.com/p/mysql-master-ha/

参考:http://blog.csdn.net/wulantian/article/details/13287975

参考:http://www.cnblogs.com/wingsless/p/4033093.html

参考:http://www.cnblogs.com/xuanzhi201111/p/4231412.html#jtss-tsina

参考:http://ylw6006.blog.51cto.com/470441/890360/

参考:http://os.51cto.com/art/201307/401702.htm

参考:http://www.it165.net/database/html/201508/13780.html

下载:http://pan.baidu.com/s/1pJ0VkSz

部署:

[root@dns packages]# tar -zxvf mha4mysql-manager-0.53.tar.gz
[root@dns mha4mysql-manager-0.53]# perl Makefile.PL
[root@dns mha4mysql-manager-0.53]# make && make install
配置有很多参数,可以看看lib\MHA下面的Config.pm代码
[root@dns mha4mysql-manager-0.53]# vim /etc/3307.cnf
[server default]
manager_log=/data1/masterha/3307_leju/manager.log
manager_workdir=/data1/masterha/3307_leju
multi_tier_slave=3
password=passwd
ping_interval=1
repl_password=x8uf7nbv5x64
repl_user=repl
shutdown_script="/samples/scripts/power_manager" //设置故障发生后关闭故障主机脚本(该脚本的主要作用是关闭主机放在发生脑裂master_pid_file=/data1/mysql/3307_leju/mysql.pid //shutdown_script脚本中需要使用的pid文件位置,通过pid文件中的pid进程号强制杀掉主库实例
ssh_user=root
user=ha[server1]
hostname=10.207.0.125
master_binlog_dir="/data1/mysql/3307_leju"
port=3307[server2]
hostname=10.207.0.126
master_binlog_dir="/data1/mysql/3307_leju"
port=3307[server3]
hostname=10.207.0.127
master_binlog_dir="/data1/mysql/3307_leju"
port=3307[server4]
hostname=10.207.0.128
master_binlog_dir="/data1/mysql/3307_leju"
port=3307
启动前检查复制关系
[root@dns bin]# masterha_check_repl --conf=/etc/masterha/3307.cnf
启动manager
masterha_manager启动有很多参数,参数说明不列举说明[root@dns bin]# masterha_manager --conf=/etc/masterha/3307.cnf --remove_dead_master_conf --ignore_last_failover

功能分析:

注意MHA需要super,select,replication slave,replication client权限,在测试MHA0.56时由于权限不够perl也没有相关报错,导致failover卡住,问题很难才定位到

MHA的故障切换是由lib/MHA/MasterFailover.pm代码完成。

编译后位置移动到/usr/local/share/perl5/MHA/MasterFailover.pm

代码主体为do_master_failover函数完成,代码片段:

sub do_master_failover {my $error_code = 1;my ( $dead_master, $new_master );eval {my @servers_config = init_config();$log->info("Starting master failover.");$log->info("* Phase 1: Configuration Check Phase..\n");$dead_master = check_settings( \@servers_config );$log->info("** Phase 1: Configuration Check Phase completed.\n");$log->info("* Phase 2: Dead Master Shutdown Phase..\n"); force_shutdown($dead_master);$log->info("* Phase 2: Dead Master Shutdown Phase completed.\n");$log->info("* Phase 3: Master Recovery Phase..\n");
$log->info("* Phase 3.1: Getting Latest Slaves Phase..\n");check_set_latest_slaves();$log->info("* Phase 3.2: Saving Dead Master's Binlog Phase..\n");save_master_binlog($dead_master);$log->info("* Phase 3.3: Determining New Master Phase..\n");my $latest_base_slave = find_latest_base_slave($dead_master);$new_master = select_new_master( $dead_master, $latest_base_slave );my ( $master_log_file, $master_log_pos ) = recover_master( $dead_master, $new_master, $latest_base_slave );$new_master->{activated} = 1;$log->info("* Phase 3: Master Recovery Phase completed.\n");$log->info("* Phase 4: Slaves Recovery Phase..\n");$error_code = recover_slaves( $dead_master, $new_master, $latest_base_slave, $master_log_file, $master_log_pos);if ( $g_remove_dead_master_conf && $error_code == 0 ) { MHA::Config::delete_block_and_save( $g_config_file, $dead_master->{id}, $log );}cleanup();};  ...
}

可以通过增加几行代码实现MHA切换通知DNS达到前端请求的切换。

# 建立连接
my $dbh = DBI->connect("DBI:mysql:database=dblayer;mysql_socket=/tmp/mysql_3307.sock","dblayer","dblayer");
# 下线主库域名,IsLive状态修改(Bind_DLZ的MySQL驱动查询增加IsLive字段判断)
my $rows = $dbh->do("UPDATE dns_records SET IsLive=0 WHERE data='$dead_master->{ip}' and port='$dead_master->{port}'");
# 获取主库host(Bind的dns_records表中使用IP和PORT对应一个唯一HOST,多实例的支持)
my $sth = $dbh->prepare("select host from dns_records where data='$dead_master->{ip}' and port='$dead_master->{port}'");
$sth->execute();
my $ref = $sth->fetchrow();
# 将新主库更新host
my $rows = $dbh->do("UPDATE dns_records SET HOST='$ref' WHERE data='$new_master->{ip}' and port='$dead_master->{port}'");
# 将切换记录到库
my $rows = $dbh->do("INSERT INTO masterfailover_log(old_master_ip,new_master_ip,port,type) values ('$dead_master->{ip}','$new_master->{ip}','$dead_master->{port}',1)");
# 断开连接$sth->finish;$dbh->disconnect();

在加入shutdown_script后,出现报错:

Thu Sep 24 14:21:42 2015 - [info]   /usr/local/mha_manager/samples/scripts/power_manager --command=status --ssh_user=root --host=10.207.0.125 --ip=10.207.0.125
Undefined subroutine &main::FIXME_xxx called at /usr/local/mha_manager/samples/scripts/power_manager line 387.
Thu Sep 24 14:21:42 2015 - [error][/usr/local/share/perl5/MHA/MasterMonitor.pm, ln235]  Failed to get power status with return code 1:0.
Thu Sep 24 14:21:42 2015 - [error][/usr/local/share/perl5/MHA/MasterMonitor.pm, ln383] Error happend on checking configurations.  at /usr/local/bin/masterha_check_repl line 48
Thu Sep 24 14:21:42 2015 - [error][/usr/local/share/perl5/MHA/MasterMonitor.pm, ln478] Error happened on monitoring servers.
Thu Sep 24 14:21:42 2015 - [info] Got exit code 1 (Not master dead).MySQL Replication Health is NOT OK!

打开power_manager可以看到,报错的部分是一个未定义函数FIXME_xxx,代码是想通过服务器管理地址进行操作,尝试将未定义函数部分去掉会出现更多问题。

在power_manager代码下面有一些注释说明,说明中有:

# killing mysqld with specified pid file. This is useful when you run multiple MySQL instances and want to stop only specified instance

power_manager --command=stopssh --host=master_server --ssh_user=root --pid_file=/var/lib/mysql/mysqld.pid

所以不在配置中添加shutdown_script,直接在MasterFailover.pm中force_shutdown_internal函数最后添加power_manager的调用。

system("/usr/local/mha_manager/samples/scripts/power_manager --command=stopssh --host='$dead_master->{ip}' --ssh_user=root --pid_file='$dead_master->{master_pid_file}'");

因为power_manager有未定义的函数,如果直接调用,在异常主库可以ssh通但是pid已经不存在或者根本ssh不通的情况下,因为stopssh函数返回值异常仍会报错未命名函数,所以改一下power_manager,注释掉一部分代码,防止killall -9 mysql mysqld。

sub stopssh {...if ($pid_file) {$command =
"\"if [ ! -e $pid_file ]; then exit 1; fi; pid=\\\`cat $pid_file\\\`; rm -f $pid_file; kill -9 \\\$pid; a=\\\`ps ax | grep $pid_file | grep -v grep | wc | awk {'print \\\$1'}\\\`; if [ \"a\\\$a\" = \"a0\" ]; then exit 10; fi; sleep 1; a=\\\`ps ax | grep $pid_file | grep -v grep | wc | awk {'print \\\$1'}\\\`; if [ \"a\\\$a\" = \"a0\" ]; then exit 10; else exit 1; fi\"";( $high_ret, $low_ret ) = MHA::ManagerUtil::exec_system("ssh $ssh_user_host $MHA::ManagerConst::SSH_OPT_CHECK $command");if ( $high_ret == $SSH_STOP_OK && $low_ret == 0 ) {print "ssh reachable. mysqld stopped. power off not needed.\n";return $high_ret;}elsif ( $high_ret == 1 && $low_ret == 0 ) {print "ssh reachable. not found $pid_file,mysqld stopped. power off not needed.\n";return 10;}else {print "Killing mysqld instance based on $pid_file failed.\n";
return 10;}
  }# 后面killall -9 mysql mysqld 注释
}

在配置里面加report_script=/usr/local/bin/send_report后

修改mha_manager/samples/scripts/send_report的代码可以通知ZABBIX和邮件通知。ZABBIX在mha_manager主机加上一个监控项,把Item设置为Zabbix trapper,Type of information设置为字符

my @array=split(/ /,$subject);
my $sender=join('',$array[0],$array[7]);system("/data1/scripts/zabbix_sender --zabbix-server serverip --port 10051 --host 'mhaserver' --key mysql.MHA --value '$sender'");
system("/bin/echo '$body' | /usr/bin/mutt -s '$subject' 'jiangxu\@test.com'");

posted on 2015-05-08 11:42 poorX 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/jiangxu67/p/4487248.html

【MySQL】MHA部署与MasterFailover代码分析相关推荐

  1. MySQL MHA部署实战

    MySQL MHA部署 环境:CentOS7 master 192.168.1.4 slave1 192.168.1.5 slave2 192.168.1.2 mha 192.168.1.7 安装依赖 ...

  2. ODBC + WIN32 API 访问MYSQL 数据库实现简单QQ用户注册和登录 的代码分析

    ODBC + WIN32 API 访问MYSQL 数据库实现简单QQ用户注册和登录 的代码分析 . /   // datadase odbc1.cpp : 定义应用程序的入口点.  //   #inc ...

  3. MySQL MHA高可用集群部署及故障切换(图文详解)

    文章目录 MySQL MHA 一.MHA概念 1.MHA 的组成 2.MHA 的特点 二.搭建MySQL+MHA 实验思路 实验环境.安装包 1.所有服务器,关闭系统防火墙和安全机制 2.修改 mas ...

  4. java毕业生设计信息学院网站分析计算机源码+系统+mysql+调试部署+lw

    java毕业生设计信息学院网站分析计算机源码+系统+mysql+调试部署+lw java毕业生设计信息学院网站分析计算机源码+系统+mysql+调试部署+lw 本源码技术栈: 项目架构:B/S架构 开 ...

  5. mysql ecos_ecos代码分析(4)

    ecos代码分析(4) 下面开始看cyg_start() < redboot/v3_0/src/main.c> void cyg_start(void) :: an no paramete ...

  6. mysql mha配置文件详解_十四、MySQL MHA 高可用配置(一)

    MHA 高可用 1.准备三台机器 IP:10.0.0.51 主机名:db01 内存:2G IP:10.0.0.52 主机名:db02 内存:2G IP:10.0.0.53 主机名:db03 内存:2G ...

  7. 持续集成与自动化部署 - jenkins sonar代码质量管理平台 部署和基础使用(五)...

    1 jenkins 安装参考链接 1.1 安装jenkins [root@test-node3 ~]# yum install -y java-1.8.0 [root@test-node3 ~]# c ...

  8. 高可用MySQL MHA介绍

    MySQL MHA介绍 MHA简介 MHA是一位日本MySQL大牛用Perl写一套MySQL故障切换方案,来保证数据库系统的高可用,在宕机的事件内(通常10-30秒),完成故障转意,部署MHA,可避免 ...

  9. 使用Hadoop和ELK进行业务代码分析!分分钟捉到Bug!

    大数据是计算领域的新高地,它有望提供一种方法来应对二十一世纪不断增长的数据生成.越来越多的大数据爱好者正在涌现,越来越多的公司正在采用各种大数据平台,并希望提出以客户为中心的解决方案,帮助他们在竞争激 ...

最新文章

  1. 计算机导论第一章试题及答案,计算机导论第一章试题
  2. [Lintcode]115. Unique Paths II/[Leetcode]63. Unique Paths II
  3. [solr] - solr5.2.1环境搭建 - 使用solr自带的jetty服务器
  4. sprintf函数_C语言源代码展示:常用转换函数实现原理
  5. 使用rpm命令卸载程序
  6. 项目启动时,出现了Consider defining a bean of type ‘xxx’ in your configuration 问题。
  7. VPS搭建zotero自动同步的webdav服务
  8. 微信状态栏隐藏 HTML,完美解决微信video视频隐藏控件和内联播放问题
  9. GIT提交代码到远程创库
  10. 单片机c语言编写音乐播放器,51单片机c语言编写电子琴+音乐播放器.doc.doc
  11. 日常开发用到的谷歌浏览器插件
  12. 永久激活win和office
  13. 身份证读卡器 浏览器插件
  14. OpenCV人脸目标检测、摄像头实时检测
  15. 2021 ICPC 南京 3.27训练赛
  16. 程序员必备的10款工具软件
  17. cocos2dx 3.17.2 升级最新的Spine
  18. esxi6.7解锁并安装macOS
  19. 现代软件工程 第一周博客记录
  20. php解析word,获得文档中的图片

热门文章

  1. 脚印:关于错误编码的管理的一些思考
  2. .NET中如何通过文本框中按回车键进行的提交数据
  3. DB2基础学习一 DB2产品介绍
  4. Windows7安全体验
  5. cool venn diagram
  6. 简单易懂棒棒哒的视频传输工具!
  7. 反射调用private或internal构造函数
  8. 简单的树形dp NOJ376 小强的Linux
  9. ubuntu编译并调试OpenJDK8源码实践
  10. 怎样健身最有效?程序员们可能还需要这些……