MHA是一位日本人用Perl写的一套MySQL故障切换方案,来保证数据库系统的高可用.在宕机的时间内(一般10—60秒内),完成故障切换,部署MHA,可避免主从一致性问题,节约购买新服务器的费用,不影响服务器性能,易安装,不改变现有部署。node
还支持在线切换,从当前运行master切换到一个新的master上面,只须要很短的时间(0.5-2秒内),此时仅仅阻塞写操做,并不影响读操做,便于主机硬件维护。mysql
yum install perl-DBD-MySQL \ perl-Config-Tiny perl-Log-Dispatch \ perl-Parallel-ForkManager -y yum install perl-Time-HiRes perl-Parallel-ForkManager -y wget http://mysql-master-ha.googlecode.com/files/mha4mysql-manager-0.55-0.el6.noarch.rpm wget http://mysql-master-ha.googlecode.com/files/mha4mysql-node-0.54-0.el6.noarch.rpm rpm -ivh mha4mysql-node-0.54-0.el6.noarch.rpm rpm -ivh mha4mysql-manager-0.55-0.el6.noarch.rpm
mkdir /etc/masterha vi /etc/masterha_default.cnf [server default] user=manager password=test_2014 ping_interval=1 repl_user=rep repl_password=rep_2014
ssh 证书安装:redis
root 用户下执行:sql
ssh-keygen -t rsa
拷贝 id_rsa.pub 到数据库节点机器上的/tmp 目录下,在数据库节点机器上执行:shell
cd /root/.ssh cat /tmp/id_rsa.put >>authorized_keys chmod 600 authorized_keys
wget http://mysql-master-ha.googlecode.com/files/mha4mysql-node-0.54-0.el6.noarch.rpm yum install perl-DBD-MySQL -y rpm -ivh mha4mysql-node-0.54-0.el6.noarch.rpm
在数据库节点上以root 用户执行:数据库
ssh-keygen -t rsa
分别拷贝id_rsa.pub 到对方机器的/tmp 目录下,而后分别执行:服务器
cd /root/.ssh cat /tmp/id_rsa.put >>authorized_keys chmod 600 authorized_keys
在master 上执行下面命令(第一次启用必须配置手动配置vip address):
ssh
ifconfig eth1:2 10.10.0.102/16
在 mha 管理节点上编辑配置文件:ide
vi /etc/masterha/test.conf [server default] ssh_user=root ping_interval=1 report_script=/usr/local/bin/send_report master_ip_failover_script=/usr/local/bin/master_ip_failover master_ip_online_change_script=/usr/local/bin/master_ip_failover [server1] hostname=10.10.0.101 master_binlog_dir=/log/mysql_test candidate_master=1 port=3306 ssh_port=22 [server2] hostname=10.10.0.100 master_binlog_dir=/log/mysql_test candidate_master=1 port=3306 ssh_port=22
主从执行:性能
mysql>grant replication slave on *.* to rep@'10.10.%' identified by 'rep_2014' ; mysql>grant all on *.* to manager@'10.10.%' identified by 'test_2014' ; mysql>flush privileges;
主上执行:
mysql>show master status;
从上执行:
mysql>change master to master_host='10.10.0.101',master_port=3306,master_user='rep',master_password='rep_2014', master_log_file='mysql-bin.000004',master_log_pos=402; mysql> start slave; mysql> stop slave; mysql> reset slave; mysql> show slave status\G;
测试ssh 配置:
/usr/bin/masterha_check_ssh --conf=/etc/masterha/test.conf
测试复制:
/usr/bin/masterha_check_repl --conf=/etc/masterha/test.conf
启用 mha :
masterha_manager --conf=/etc/masterha/test.conf
master 切换:
masterha_master_switch --master_state=alive --conf=/etc/masterha/test.conf
master_ip_failover 脚本:
cat /usr/local/bin/master_ip_failover #!/usr/bin/env perl use strict; use warnings FATAL => 'all'; use Getopt::Long; my ( $command, $ssh_user, $orig_master_host, $orig_master_ip, $orig_master_port, $new_master_host, $new_master_ip, $new_master_port ); my $vip = '10.10.0.102/16'; # Virtual IP my $key = "2"; my $ssh_start_vip = "/sbin/ifconfig eth1:$key $vip"; my $ssh_stop_vip = "/sbin/ifconfig eth1:$key down"; $ssh_user = "root"; GetOptions( 'command=s' => \$command, 'ssh_user=s' => \$ssh_user, 'orig_master_host=s' => \$orig_master_host, 'orig_master_ip=s' => \$orig_master_ip, 'orig_master_port=i' => \$orig_master_port, 'new_master_host=s' => \$new_master_host, 'new_master_ip=s' => \$new_master_ip, 'new_master_port=i' => \$new_master_port, ); exit &main(); sub main { print "\n\nIN SCRIPT TEST====$ssh_stop_vip==$ssh_start_vip===\n\n"; if ( $command eq "stop" || $command eq "stopssh" ) { # $orig_master_host, $orig_master_ip, $orig_master_port are passed. # If you manage master ip address at global catalog database, # invalidate orig_master_ip here. my $exit_code = 1; eval { print "Disabling the VIP on old master: $orig_master_host \n"; &stop_vip(); $exit_code = 0; }; if ($@) { warn "Got Error: $@\n"; exit $exit_code; } exit $exit_code; } elsif ( $command eq "start" ) { # all arguments are passed. # If you manage master ip address at global catalog database, # activate new_master_ip here. # You can also grant write access (create user, set read_only=0, etc) here. my $exit_code = 10; eval { print "Enabling the VIP - $vip on the new master - $new_master_host \n"; &start_vip(); $exit_code = 0; }; if ($@) { warn $@; exit $exit_code; } exit $exit_code; } elsif ( $command eq "status" ) { print "Checking the Status of the script.. OK \n"; `ssh $ssh_user\@cluster1 \" $ssh_start_vip \"`; exit 0; } else { &usage(); exit 1; } } # A simple system call that enable the VIP on the new master sub start_vip() { `ssh $ssh_user\@$new_master_host \" $ssh_start_vip \"`; } # A simple system call that disable the VIP on the old_master sub stop_vip() { `ssh $ssh_user\@$orig_master_host \" $ssh_stop_vip \"`; } sub usage { print "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"; }
cat send_report #!/usr/bin/perl # Copyright (C) 2011 DeNA Co.,Ltd. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ## Note: This is a sample script and is not complete. Modify the script based on your environment. use strict; use warnings FATAL => 'all'; use Getopt::Long; #new_master_host and new_slave_hosts are set only when recovering master succeeded my ( $dead_master_host, $new_master_host, $new_slave_hosts, $subject, $body ); GetOptions( 'orig_master_host=s' => \$dead_master_host, 'new_master_host=s' => \$new_master_host, 'new_slave_hosts=s' => \$new_slave_hosts, 'subject=s' => \$subject, 'body=s' => \$body, ); # Do whatever you want here exit 0;