mysql-master-ha

mysql 做热备和高可用的方法有很多种, 比如:

mmm: http://mysql-mmm.org/

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

heartbeat+brdb: http://lin128.blog.51cto.com/407924/279411 http://www.centos.bz/2012/03/achieve-drbd-high-availability-with-heartbeat/

cluster(使用ndb引擎):http://database.51cto.com/art/201008/218326.htm

双master+keeplived: http://database.51cto.com/art/201012/237204.htm

双master: http://yunnick.iteye.com/blog/1845301

这里我们不介绍其他的方式以及优缺点,只介绍mha的安装过程。

首先我这篇文档参考了如下网页:

官方wiki: https://code.google.com/p/mysql-master-ha/wiki/Tutorial

使用MHA做mysql的高可用:http://qiufengy.blog.51cto.com/391990/848468

Mysql5.5部署MHA: http://ylw6006.blog.51cto.com/470441/890360

mysql High Availability -MHA: http://www.vmcd.org/2012/04/mysql-high-availability-mha/

MySQL高可用性大杀器之MHA: http://huoding.com/2011/12/18/139

mysql-mha高可用 : http://blog.chinaunix.net/uid-28437434-id-3476641.html

另外有个slide讲mha的,可以看看:http://www.slideshare.net/ylouis83/mysqlmha

准备环境

官方文档是用了4台机器,所以我也用了4台机器,分别是:

host1: 172.16.21.15 #manager, monitor ubuntu 13.04

host2: 172.16.21.23 #master ubuntu 12.04 server

hots3: 172.16.21.50 #备选master ubuntu 12.04 server

host4: 172.16.21.48 #slave ubuntu 12.04 server

mha自己不构建复制(replication)环境,所以它可以重用以前的复制结构,关于mysql复制的拓扑结构可以参考此文章:http://blog.csdn.net/hguisu/article/details/7325124

我们这里使用mysql半同步复制(semisync)架构, 半同步复制的介绍他搭建见此:http://hzcsky.blog.51cto.com/1560073/820859 http://haiker.iteye.com/blog/1632697

mysql半同步复制需要mysql版本5.5以上,另mysql 5.6以后开源协议有变, 推荐percona: http://www.percona.com/software/percona-server 或mariadb, 不过ubuntu中用apt-get 安装软件实在是很方便,我还是使用apt-get install mysql-server-5.5 来安装mysql的。

在host2, host3, host4 安装mysql后,更改其/etc/mysql/my.cnf 添加如下内容:

server-id = 1 #不同的host server_id 一定要不一样,我这里host2为1, host3 为2, host4 为3

log_bin = /var/log/mysql/mysql-bin.log #为了安全,应该创建一个目录存放binlog的,不过我很懒,就放到log目录了,生产环境不能这样

replicate_ignore_db = mysql

ps: 上面和下面所有的命令最好都使用root用户执行,我曾经使用非 root用户,最后发现很烦, 另ubuntu 默认root是不可以ssh登陆的,要先:passwd root 给root添加密码,这样root就可以ssh登陆了。

半同步复制开启

master, host2上:

  1. mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';
  2. mysql> set global rpl_semi_sync_master_enabled=1;
  3. mysql> set global rpl_semi_sync_master_timeout=1000;
  4. mysql> show global status like 'rpl%';

为了让mysql在重启时自动加载该功能,在/etc/mysql/my.cnf 加入:

rpl_semi_sync_master_enabled=1

rpl_semi_sync_master_timeout=1000

备选master, host3 上:

  1. mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';
  2. mysql> set global rpl_semi_sync_master_enabled=1;
  3. mysql> set global rpl_semi_sync_master_timeout=1000;
  4. mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
  5. mysql> set global rpl_semi_sync_slave_enabled=1;

在/etc/mysql/my.cnf中加入:

rpl_semi_sync_master_enabled=1 rpl_semi_sync_master_timeout=1000 rpl_semi_sync_slave_enabled=1

slave, host4 上:

  1. mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
  2. mysql> set global rpl_semi_sync_slave_enabled=1;

在/etc/mysql/my.cnf中加入:

rpl_semi_sync_slave_enabled=1

在备用节点和从节点的/etc/mysql/my.cnf中加入选项:

read_only=1 #这个设置待商榷,备选master设为read only之后,master转移到备选master后数据库不可写(有super权限的用户还是可写)

relay_log_purge=0


在master上:

  1. mysql> grant replication slave on *.* to repl@'172.16.21.%' identified by 'repl';
  2. mysql> show master status;
  3. 记录下 File”和“Position”即当前主库使用的二进制日志名称和位置。

在备选master和slave上:

  1. mysql> change master to master_host="172.16.21.23",master_user="repl",master_password="repl",master_log_file="bin-log.000001",master_log_pos=255;

master_log_file 和 master_log_pos 是上面记下的东西。

在备选master上:

  1. mysql> grant replication slave on *.* to repl@'172.16.21.%' identified by 'repl';

然后在备选master和slave上:

  1. mysql>start slave
  2. mysql>show slave status\G
  3. # 如果 Slave_IO_Running: Yes 和 Slave_SQL_Running: Yes 则说明主从配置成功
  4. # 还可以到master上执行 Mysql>show global status like “rpl%”; 如果Rpl_semi_sync_master_clients 是2.说明半同步复制正常

安装MHA

下载MHA Node 0.54: https://code.google.com/p/mysql-master-ha/downloads/detail?name=mha4mysql-node_0.54-0_all.deb&can=2&q=

和 MHA Manager 0.55: https://code.google.com/p/mysql-master-ha/downloads/detail?name=mha4mysql-manager_0.55-0_all.deb&can=2&q=

其他版本的文件在: https://code.google.com/p/mysql-master-ha/downloads/list

先在4台机器上安装MHA Node:

  1. apt-get install libdbd-mysql-perl
  2. dpkg -i mha4mysql-node_0.54-0_all.deb

在manager/host1 上安装MHA Manager:

  1. apt-get install libdbd-mysql-perl
  2. apt-get install libconfig-tiny-perl
  3. apt-get install liblog-dispatch-perl
  4. apt-get install libparallel-forkmanager-perl
  5. dpkg -i mha4mysql-manager_0.55-0_all.deb
  6. mkdir -p /masterha/app1/

在manager上创建配置文件/etc/app1.cnf, 内容如下:

  1. [server default]
  2. manager_workdir=/masterha/app1
  3. manager_log=/masterha/app1/manager.log
  4. #remote_workdir=/usr/local/mysql
  5. #mysql user and password
  6. user=root
  7. password=root
  8. ssh_user=root
  9. repl_user=repl
  10. repl_password=repl
  11. ping_interval=1
  12. shutdown_script=""
  13. #master_ip_failover_script=/usr/local/bin/master_ip_failover
  14. #master_ip_online_change_script=/usr/local/bin/master_ip_online_change_script
  15. #report_script=""
  16.  
  17. [server1]
  18. hostname=master
  19. master_binlog_dir=/var/log/mysql
  20. candidate_master=1
  21.  
  22. [server2]
  23. hostname=172.16.21.50
  24. master_binlog_dir=/var/log/mysql
  25. candidate_master=1
  26. [server3]
  27.  
  28. hostname=172.16.21.48
  29. master_binlog_dir=/var/log/mysql
  30. no_master=1

然后给mysql赋权限, 在3台mysql机器上执行如下语句:

  1. mysql> grant all on *.* to root@'172.16.21.15' identified by 'root';
  2. mysql> grant all on *.* to root@'172.16.21.23' identified by 'root';
  3. mysql> grant all on *.* to root@'172.16.21.50' identified by 'root';
  4. mysql> grant all on *.* to root@'172.16.21.48' identified by 'root';

或者也可执行如下语句:

  1. mysql> grant all on *.* to root@'172.16.21.%' identified by 'root';

然后建立ssh无密码登录环境:

在manager上:

  1. ssh-keygen -t rsa
  2. ssh-copy-id root@172.16.21.23
  3. ssh-copy-id root@172.16.21.50
  4. ssh-copy-id root@172.16.21.48

在master上:

  1. ssh-keygen -t rsa
  2. ssh-copy-id root@172.16.21.50
  3. ssh-copy-id root@172.16.21.48

在备选master上:

  1. ssh-keygen -t rsa
  2. ssh-copy-id root@172.16.21.23
  3. ssh-copy-id root@172.16.21.48

在slave上:

  1. ssh-keygen -t rsa
  2. ssh-copy-id root@172.16.21.23
  3. ssh-copy-id root@172.16.21.50

最后在manager上执行ssh登录检查:

  1. masterha_check_ssh --conf=/etc/app1.cnf

和复制情况检查:

  1. masterha_check_repl --conf=/etc/app1.cnf

然后可以启动manager:

  1. nohup masterha_manager --conf=/etc/app1.cnf < /dev/null > /masterha/app1/manager.log 2>&1 &

检查manager状态:

  1. masterha_check_status --conf=/etc/app1.cnf

停止manager:

  1. masterha_stop --conf=/etc/app1.cnf
  2. # 如果不能停止, 加 --abort选项

在备选master和slave节点 crontab -e 添加计划任务

  1. 00 00 * * * /usr/local/bin/purge_relay_logs user=root password=root disable_relay_log_purge >> /var/log/purge_relay_logs.log 2>&1

测试和恢复MHA

manager上 tail -f /masterha/app1/manager.log 监控log

然后在master上 echo c > /proc/sysrq-trigger 使其死机

在log里可以看到master转移到备选master了

除了被动转移master,还可以手动转移master,如下:

  1. masterha_master_switch --conf=/etc/app1.cnf --master_state=dead --dead_master_host=...
  2. masterha_master_switch --conf=/etc/app1.cnf --master_state=alive --new_master_host=...

注:针对原来的MySQL主服务器是否已经宕机,执行命令所需的参数有所不同。

MHA有个不方便的地方是,无论宕机导致的master切换还是手动切换master, 原来的master都不在MHA架构内了,重新启动也不会加入,必须手动加入。

手动加入和上面的步骤类似,先把当前master数据复制到要加入的机器,然后change master,再start slave, 关键在做这一过程中,系统不能写入,这点要人命。

master_ip_failover, shutdown_script等脚本

MHA在配置文件里设置使得一些脚本在特定时候被执行

shutdown_script: MHA用于关闭master的脚本,在代码samples/scripts有一个样例脚本power_manager, 脚本详解可看:https://code.google.com/p/mysql-master-ha/wiki/Parameters#shutdown_script

master_ip_failover_script, master_ip_online_change_script: 发生在master切换的时候,为了应用继续可用,调用这两个脚本做些处理。refs:

  1. 说到Failover,通常有两种方式:一种是虚拟IP地址,一种是全局配置文件。
  2. MHA并没有限定使用哪一种方式,而是让用户自己选择,虚拟IP地址的方式会牵扯到其它的软件,这里就不赘述了,
  3. 以下简单说说全局配置文件,以PHP为实现语言,代码如下:
  4.  
  5. #!/usr/bin/env php
  6. <?php
  7. $longopts = array(
  8. 'command:',
  9. 'ssh_user:',
  10. 'orig_master_host:',
  11. 'orig_master_ip:',
  12. 'orig_master_port:',
  13. 'new_master_host::',
  14. 'new_master_ip::',
  15. 'new_master_port::',
  16. );
  17.  
  18. $options = getopt(null, $longopts);
  19.  
  20. if ($options['command'] == 'start') {
  21. $params = array(
  22. 'ip' => $options['new_master_ip'],
  23. 'port' => $options['new_master_port'],
  24. );
  25.  
  26. $string = '<?php return ' . var_export($params, true) . '; ?>';
  27.  
  28. file_put_contents('config.php', $string, LOCK_EX);
  29. }
  30.  
  31. exit(0);
  32. ?>
  33. 注:用其它语言实现这个脚本也是OK的,最后别忘了给脚本加上可执行属性。
  34.  
  35. 如果要测试效果的话,可以kill掉当前的MySQL主服务器,稍等片刻,MHA就会把某台MySQL从服务器提升为新的MySQL主服务器,
  36. 并调用master_ip_failover_script脚本,
  37. 如上所示,我们在master_ip_failover_script脚本里可以把新的MySQL主服务器的ipport信息持久化到配置文件里,
  38. 这样应用就可以使用新的配置了。
  39.  
  40. 有时候需要手动切换MySQL主服务器,可以使用masterha_master_switch命令,
  41. 不过它调用的不是master_ip_failover_script脚本,而是master_ip_online_change_script脚本,但调用参数类似,脚本可以互用。

虚拟ip涉及到其他软件,我们稍后讲

report_script: You might want to send a report (i.e. e-mail) when failover has completed or ended with errors. 接受如下参数:

  1. --orig_master_host=(dead master's hostname)
  2. --new_master_host=(new master's hostname)
  3. --new_slave_hosts=(new slaves' hostnames, delimited by commas)
  4. --subject=(mail subject)
  5. --body=(body)

这些脚本在代码包里都有示例,但都是perl的,你可以用其他脚本语言自己来写。

配置虚拟IP

有个简单的方法添加虚拟ip, 用ifconfig命令, 参考此文章:http://blog.csdn.net/csfreebird/article/details/7996318

添加VIP:

  1. /sbin/ifconfig eth0:1 172.16.21.119/24

删除VIP:

  1. /sbin/ifconfig eth0:1 down

把配置写入/etc/network/interfaces, 使其重启有效:

  1. auto lo
  2. iface lo inet loopback
  3.  
  4. auto eth0:0
  5. iface eth0:0 inet static
  6. name Ethernet alias LAN card
  7. address 10.112.18.191
  8. netmask 255.255.255.0
  9. broadcast 10.112.18.255
  10. network 10.112.18.0

网上找了一个master_ip_failover脚本就是用此方法更改VIP:

  1. #!/usr/bin/env perl
  2. use strict;
  3. use warnings FATAL => 'all';
  4.  
  5. use Getopt::Long;
  6.  
  7. my (
  8. $command, $ssh_user, $orig_master_host, $orig_master_ip,
  9. $orig_master_port, $new_master_host, $new_master_ip, $new_master_port
  10. );
  11.  
  12. my $vip = '172.16.21.119/24'; # Virtual IP
  13. my $key = "1";
  14. my $ssh_start_vip = "/sbin/ifconfig eth0:$key $vip";
  15. my $ssh_stop_vip = "/sbin/ifconfig eth0:$key down";
  16.  
  17. GetOptions(
  18. 'command=s' => \$command,
  19. 'ssh_user=s' => \$ssh_user,
  20. 'orig_master_host=s' => \$orig_master_host,
  21. 'orig_master_ip=s' => \$orig_master_ip,
  22. 'orig_master_port=i' => \$orig_master_port,
  23. 'new_master_host=s' => \$new_master_host,
  24. 'new_master_ip=s' => \$new_master_ip,
  25. 'new_master_port=i' => \$new_master_port,
  26. );
  27.  
  28. exit &main();
  29.  
  30. sub main {
  31.  
  32. print "\n\nIN SCRIPT TEST====$ssh_stop_vip==$ssh_start_vip===\n\n";
  33.  
  34. if ( $command eq "stop" || $command eq "stopssh" ) {
  35.  
  36. # $orig_master_host, $orig_master_ip, $orig_master_port are passed.
  37. # If you manage master ip address at global catalog database,
  38. # invalidate orig_master_ip here.
  39. my $exit_code = 1;
  40. eval {
  41. print "Disabling the VIP on old master: $orig_master_host \n";
  42. &stop_vip();
  43. $exit_code = 0;
  44. };
  45. if ($@) {
  46. warn "Got Error: $@\n";
  47. exit $exit_code;
  48. }
  49. exit $exit_code;
  50. }
  51. elsif ( $command eq "start" ) {
  52.  
  53. # all arguments are passed.
  54. # If you manage master ip address at global catalog database,
  55. # activate new_master_ip here.
  56. # You can also grant write access (create user, set read_only=0, etc) here.
  57. my $exit_code = 10;
  58. eval {
  59. print "Enabling the VIP - $vip on the new master - $new_master_host \n";
  60. &start_vip();
  61. $exit_code = 0;
  62. };
  63. if ($@) {
  64. warn $@;
  65. exit $exit_code;
  66. }
  67. exit $exit_code;
  68. }
  69. elsif ( $command eq "status" ) {
  70. print "Checking the Status of the script.. OK \n";
  71. `ssh $ssh_user\@cluster1 \" $ssh_start_vip \"`;
  72. exit 0;
  73. }
  74. else {
  75. &usage();
  76. exit 1;
  77. }
  78. }
  79.  
  80. # A simple system call that enable the VIP on the new master
  81. sub start_vip() {
  82. `ssh $ssh_user\@$new_master_host \" $ssh_start_vip \"`;
  83. }
  84. # A simple system call that disable the VIP on the old_master
  85. sub stop_vip() {
  86. `ssh $ssh_user\@$orig_master_host \" $ssh_stop_vip \"`;
  87. }
  88.  
  89. sub usage {
  90. print
  91. "Usage: master_ip_failover --command=start|stop|stopssh|status --orig_master_host=host --orig_master_ip=ip --orig_master_port=port --new_master_host=host --new_master_ip=ip --new_master_port=port\n";
  92. }

将此文档复制两次到/usr/local/bin, 分别命名为master_ip_failover 和master_ip_online_change_script

然后将/etc/app1.cnf 中下面两行注释去掉:

  1. master_ip_failover_script=/usr/local/bin/master_ip_failover
  2. master_ip_online_change_script=/usr/local/bin/master_ip_online_change_script
 

mysql HA方案: MHA的更多相关文章

  1. MySQL HA方案之MySQL半复制+MHA+Keepalived+Atlas+LVS[转]

    MySQL HA方案之MySQL半复制+MHA+Keepalived+Atlas+LVS 简介 目前Mysql高可用的方案有好多,比如MMM,heartbeat+drbd,Cluster等,还有per ...

  2. 理解 OpenStack 高可用(HA) (6): MySQL HA

    本系列会分析OpenStack 的高可用性(HA)概念和解决方案: (1)OpenStack 高可用方案概述 (2)Neutron L3 Agent HA - VRRP (虚拟路由冗余协议) (3)N ...

  3. mysql高可用方案MHA介绍

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

  4. mysql 高可用方案MHA介绍

    概述 MHA是一位日本MySQL大牛用Perl写的一套MySQL故障切换方案,来保证数据库系统的高可用.在宕机的时间内(通常10—30秒内),完成故障切换,部署MHA,可避免主从一致性问题,节约购买新 ...

  5. MySQL高可用方案--MHA部署及故障转移

    架构设计及必要配置 主机环境 IP                 主机名             担任角色 192.168.192.128  node_master    MySQL-Master| ...

  6. MySQL高可用方案MHA自动Failover与手动Failover的实践及原理

    集群信息 角色                             IP地址                 ServerID      类型 Master                     ...

  7. MySQL高可用方案MHA在线切换的步骤及原理

    在日常工作中,会碰到如下的场景,如mysql数据库升级,主服务器硬件升级等,这个时候就需要将写操作切换到另外一台服务器上,那么如何进行在线切换呢?同时,要求切换过程短,对业务的影响比较小. MHA就提 ...

  8. 提升mysql服务器性能(HA MMM MHA MaxScale)

    原文:提升mysql服务器性能(HA MMM MHA MaxScale) 版权声明:皆为本人原创,复制必究 https://blog.csdn.net/m493096871/article/detai ...

  9. 如何基于Azure平台实现MySQL HA(方法论篇)

    我们都知道,相较于传统的数据中心,Pulic cloud也有劣势,比如说数据库的HA,很多熟悉公有云平台的读者都知道,因为出于安全性性考虑以及一些技术条件的限制,很多本地数据中心的mysql HA方法 ...

随机推荐

  1. rsync、ssh备份

    Linux系统需求 为了实现这个备份程序,需要准备一个外部驱动器.您可以将备份写到一个外部USB磁盘,但这样做效率不高.因此,我假设您将备份写到位于网络某处的服务器中.这台服务器要为带有SSH和rsy ...

  2. 超轻量级PHP SQL数据库框架

    <?php /** * ! Medoo 0.8.5 - Copyright 2013, Angel Lai - MIT license - http://medoo.in */ class me ...

  3. 卡特兰数(Catalan)简介

    Catalan序列是一个整数序列,其通项公式是 h(n)=C(2n,n)/(n+1) (n=0,1,2,...) 其前几项为 : 1, 1, 2, 5, 14, 42, 132, 429, 1430, ...

  4. CodeIgniter中的session处理

    在CI中你可以这样很简单地装载library:     $this->load->library('newclass');    注意系统中会有两个library目录,一个是system/ ...

  5. 盘点:移动服务 #AzureChat

    感谢大家帮助我们顺利推出史无前例的 #AzureChat.移动服务和 Notification Hub 是 Windows Azure 平台上令人振奋的服务.我们很高兴能借这次在线讨论的机会,倾听各位 ...

  6. Git基础 1 ---- 版本控制系统的介绍

    1 Git 1 版本控制系统 vcs - version control system 2 版本控制是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统 3 版本控制系统的主要功能 1 ...

  7. Your Job Is Not to Write Code

    I am lucky enough to work with a small team of fantastic engineers who truly care about their custom ...

  8. JqueryMobile新手问题大全

    Jquery mobile 新手问题总汇 34 2013-04-22 / 分类:JqueryMobile / 标签:JqueryMobile,Jqm 此文章将会持续更新,主要收录一些新手比较常见的问题 ...

  9. [LeetCode]题解(python):012-Integer to Roman

    题目来源: https://leetcode.com/problems/integer-to-roman/ 题意分析: 这道题是要把在区间[1-3999]的数字转化成罗马数字. 题目思路: 只要知道了 ...

  10. (Problem 22)Names scores

    Using names.txt (right click and 'Save Link/Target As...'), a 46K text file containing over five-tho ...