MHA高可用

MHA简介

MHA(Master High Availability)目前在MySQL高可用方面是一个相对成熟的解决方案,它由日本DeNA公司youshimaton(现就职于Facebook公司)开发,是一套优秀的作为MySQL高可用性环境下故障切换和主从提升的高可用软件。
在MySQL故障切换过程中,MHA能做到在10~30秒之内自动完成数据库的故障切换操作,并且在进行故障切换的过程中,MHA能在最大程度上保证数据的一致性,以达到真正意义上的高可用。
该软件由两部分组成:MHA Manager(管理节点)和MHA Node(数据节点)。

MHA功能

MHA能够在较短的时间内实现自动故障检测和故障转移,通常在10-30秒以内;
在复制框架中,MHA能够很好地解决复制过程中的数据一致性问题,由于不需要在现有的 replication中添加额外的服务器,仅需要一个manager节点,而一个Manager能管理多套复制,所以能大大地节约服务器的数量
另外,安装简单,无性能损耗,以及不需要修改现 有的复制部署也是它的优势之处。
MHA还提供在线主库切换的功能,能够安全地切换当前运行的主库到一个新的主库中 (通过将从库提升为主库),大概0.5-2秒内即可完成。
MHA Manager可以单独部署在一台独立的机器上管理多个master-slave集群,也可以部署在一台slave节点上。MHA Node运行在每台MySQL服务器上,MHA Manager会定时探测集群中的master节点,当master出现故障时,它可以自动将最新数据的slave提升为新的master,然后将所有其他的slave重新指向新的master。整个故障转移过程对应用程序完全透明。

MHA工作原理

工作原理说明:
1、保存master上的所有binlog事件
2、找到含有最新binlog位置点的slave
3、通过中继日志将数据恢复到其他的slave
4、将包含最新binlog位置点的slave提升为master
5、将其他从库slave指向新的master原slave01 并开启主从复制
6、将保存下来的binlog恢复到新的master上

MHA工具介绍

MHA软件由两部分组成,Manager工具包和Node工具包

masterha_check_ssh               #检査 MHA 的 ssh-key
masterha_check_repl              #检査主从复制情况
masterha_manger                  #启动MHA
masterha_check_status            #检测MHA的运行状态^
masterha_mast er_monitor         #检测master是否宕机
masterha_mast er_switch          #手动故障转移—
masterha_conf_host               #手动添加server倍息
masterha_secondary_check         #建立TCP连接从远程服务器v
masterha_stop                    #停止MHA 

Node工具包主要包括以下几个工具:

save_binary_1ogs                 #保存宕机的master的binlog
apply_diff_relay_logs            #识别relay log的差异
filter_mysqlbinlog               #防止回滚事件一MHA已不再使用这个工具
purge_relay_logs                 #清除中继曰志一不会阻塞SQL线程 

MHA的优点

1、自动故障转移
2、主库崩溃不存在数据不一致的情况
3、不需要对当前的mysql环境做重大修改
4、不需要添加额外的服务器
5、性能优秀,可以工作再半同步和异步复制框架
6、只要replication支持的存储引擎mha都支持

MHA部署

本次部署包括 mysql主从同步+MHA高可用+keepalived
mha版本0.56
数据库5.7

机器名 IP地址 功能划分
db01 172.16.1.51 主 keepalived node
db02 172.16.1.52 从 keepalived node
db03 172.16.1.53 从 manager node

基础环境部署

基础内容

关闭防火墙和selinux

systemctl stop firewalld && setenforce 0

下载数据库
安装mysql, 默认5.7版本, 使用本地yum源下载

yum install mysql-community-server -y

修改配置文件

修改配置文件/etc/my.cnf server-id 以IP最后一段命名
db01的内容

[root@db01 ~]# vi /etc/my.cnf   #使用vi打开
[mysqld]
server-id=51
log-bin = master-log
relay-log = relay-log
skip_name_resolve  

db02的内容

[root@db02 ~]# vi /etc/my.cnf
server-id=52
relay-log = relay-log
log-bin = master-log
read_only = ON
relay_log_purge = 0
skip_name_resolve
log_slave_updates = 1

db03的内容

[root@db03 ~]# vi /etc/my.cnf
[mysqld]
server-id = 53
relay-log = relay-log
log-bin = master-log
read_only = ON
relay_log_purge = 0
skip_name_resolve
log_slave_updates = 1

启动数据库, 并加入开机自启动

systemctl start mysqld && systemctl enable mysqld

修改密码及导入数据
修改密码

登陆mysql数据库  [password中填写上一步过滤的密码]
mysql -uroot -p$(awk '/temporary password/{print $NF}' /var/log/mysqld.log)
修改数据库密码
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'Bgx123.com';
mysql> exit

导入原先的数据(三台机器都要操作)

mysql -uroot -pBgx123.com < /tmp/db-all.sql  #导入原有的数据库即可

然后重启mysql

systemctl restart mysqld

增加用户

db01主库的操作

[root@db01 ~]# mysql -uroot -pBgx123.com
mysql> grant all on *.* to 'all'@'%' identified by 'Bgx123.com';   #这个是配置远程连接规则
mysql> grant replication slave, replication client  on *.*
to 'rep'@'172.16.1.%' identified by 'Rep123.com';  #授权, 允许能够远程连接的主机(replicaiton)
mysql> flush privileges;

在 master 上进行授权
在所有 Mysql进行授权
拥有管理权限的用户可在本地网络中有其他节点上远程访问。 mha为manager管理用户

mysql> grant all on *.* to 'mha'@'172.16.%.%' identified by 'Bgx123.com';  #所有数据库都要进行授权
mysql> flush privileges;
#mysql 新设置用户或更改密码后需用flush privileges刷新MySQL的系统权限相关表,否则会出现拒绝访问

安装MHA软件

(在三个节点上都装mha的node软件)
在db03(manager监控端)安装manager

[root@db01 ~]# ll
-rw-r--r--  1 root root 36326 Oct 24 20:11 mha4mysql-node-0.56-0.el6.noarch.rpm
[root@db02 ~]# ll
-rw-r--r--  1 root root 36326 Oct 24 20:11 mha4mysql-node-0.56-0.el6.noarch.rpm
[root@db03 ~]# ll
-rw-r--r--  1 root root 87119 Oct 24 20:11 mha4mysql-manager-0.56-0.el6.noarch.rpm
-rw-r--r--  1 root root 36326 Oct 24 20:11 mha4mysql-node-0.56-0.el6.noarch.rpm

首先要确保yum源有base源和epel源而且可以上网
因为mha安装会安装依赖

[root@db02 ~]# ll /etc/yum.repos.d/
-rw-r--r-- 1 root root 2523 Sep  4 17:06 CentOS-Base.repo
-rw-r--r-- 1 root root  664 Sep  4 17:06 epel.repo

然后直接使用yum install 安装
db03 manager node都要安装 其他两台只安装node

 [root@db01 ~]# yum install mha4mysql-node-0.56-0.el6.noarch.rpm -y
[root@db02 ~]# yum install -y mha4mysql-node-0.56-0.el6.noarch.rpm
[root@db03 ~]# yum install mha4mysql-manager-0.56-0.el6.noarch.rpm
[root@db03 ~]# yum install mha4mysql-node-0.56-0.el6.noarch.rpm

配置manager

mha配置文件内容

[root@db03 ~]# mkdir /etc/mha_master/
[root@db03 ~]# cat /etc/mha_master/mha.cnf
[server default]
user=mha
password=Bgx123.com
manager_workdir=/etc/mha_master/app1
manager_log=/etc/mha_master/manager.log
remote_workdir=/mydata/mha_master/app1
ssh_user=root
repl_user=rep
repl_password=Rep123.com
ping_interval=1
[server1]
hostname=172.16.1.51
port=3306
candidate_master=1
[server2]
hostname=172.16.1.52
port=3306
candidate_master=1
#[server3]
#hostname=172.16.1.53
#port=3306
#candidate_master=1

配置三台机器的ssh互信(三台都要操作)在配置MHA会要求三台数据库无密码通信

ssh-keygen -t rsa
ssh-copy-id -i /root/.ssh/id_rsa.pub root@172.16.1.51
ssh-copy-id -i /root/.ssh/id_rsa.pub root@172.16.1.52
ssh-copy-id -i /root/.ssh/id_rsa.pub root@172.16.1.31
#测试是否成功
ssh 172.16.1.52   不用输入密码就证明成功

指向Master 只在db02 db03操作
在两个salve节点(从库)上执行,只读限制(防止意外被写数据,很重要)

mysql> set global read_only=1;
mysql> change master to
    -> master_host='172.16.1.51',
    -> master_user='rep',
    -> master_password='Rep123.com';
mysql> start slave;
mysql> show slave status\G; #查看slave IO和slave sql是否都正常 Yes就是正常的
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes

测试配置

测试连通性

[root@db03 ~]# masterha_check_ssh -conf=/etc/mha_master/mha.cnf  #最后一行如下图即为成功

确认上一步连通性没问题后开始下一步检查
检查管理的MySQL复制集群的连接配置参数是否OK

[root@db03 ~]# masterha_check_repl -conf=/etc/mha_master/mha.cnf

底部显示OK即为正常

配置VIP漂移

配置Keepalived

使用keepalived做VIP转移
keepalived只在 db01 db02上安装

[root@db01 ~]# yum install keepalived -y
[root@db02 ~]# yum install keepalived -y

keepalived db01的配置文件内容

[root@db01 ~]# cat /etc/keepalived/keepalived.conf
global_defs {
    router_id db01
}
vrrp_instance VI_1 {
    state MASTER
    interface eth1
    virtual_router_id 50
    priority 150
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
}
    virtual_ipaddress {
        172.16.1.66/24 dev eth1
    }
}

启动keepalived

systemctl start keepalived.service

keepalived db02的配置文件内容

[root@db02 ~]# cat /etc/keepalived/keepalived.conf
global_defs {
    router_id db02
}
vrrp_instance VI_1 {
    state BACKUP
    interface eth1
    virtual_router_id 50
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        172.16.1.66/24 dev eth1
    }
}

配置完不要忘记启动

systemctl start keepalived.service

配置脚本内容

写入脚本内容(我们使用的yum安装 没有自带的脚本 所以自己写)见文件包内

[root@db03 ~]# 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 = '172.16.1.66';
my $ssh_start_vip = "systemctl start keepalived";
my $ssh_stop_vip = "systemctl stop keepalived";
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" ) {
        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" ) {
        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";
        exit 0;
    }
    else {
        &usage();
        exit 1;
    }
}
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";
}

给脚本增加执行权限不然会报错

[root@db03 ~]# chmod +x /usr/local/bin/master_ip_failover

在db03的配置文件内加入一行(在原有内容的基础上增加)

[root@db03 ~]# vim /etc/mha_master/mha.cnf
master_ip_failover_script= /usr/local/bin/master_ip_failover

测试连通性

[root@db03 ~]# masterha_check_ssh -conf=/etc/mha_master/mha.cnf

测试配置

[root@db03 ~]# masterha_check_repl -conf=/etc/mha_master/mha.cnf

启动mha (在db03上执行)

nohup masterha_manager -conf=/etc/mha_master/mha.cnf &> /etc/mha_master/manager.log &
[1] 13530  #这个号码每次都会不一样
[root@db03 ~]# masterha_check_status -conf=/etc/mha_master/mha.cnf
mha (pid:13530) is running(0:PING_OK), master:172.16.1.51

上面的信息中“mha (pid:13530) is running(0:PING_OK)”表示MHA服务运行OK,否则, 则会显示为类似“mha is stopped(1:NOT_RUNNING).”

如果,我们想要停止 MHA ,则需要使用 stop 命令:
[root@manager ~]# masterha_stop -conf=/etc/mha_master/mha.cnf

测试 MHA 故障转移

先在db03打开日志

[root@db03 ~]# tail -f /etc/mha_master/manager.log

主库 db01 关闭 mariadb 服务,模拟主节点数据崩溃

[root@db01 ~]# systemctl stop mysqld

转移后的恢复

重新启动主库后
db01的操作(不要忘记重启)

[root@db01 ~]# systemctl start mysqld
[root@db01 ~]# systemctl start keepalived.service 

在从库上执行以下命令(重新设置从库)

mysql> stop slave;
mysql> reset slave;
mysql> CHANGE MASTER TO
    MASTER_HOST=' 172.16.1.51',
    MASTER_USER='rep',
    MASTER_PASSWORD=' Rep123.com',
    MASTER_PORT=3306,
    MASTER_LOG_FILE='master-log.000005',
    MASTER_LOG_POS=154;
mysql> start slave;
mysql> show slave status\G;

db03的操作 (重新启动mha之前一定要删除这个目录下的文件 不然下次转移报错)

[root@db03 ~]# rm -f  /etc/mha_master/app1/*

检查

[root@db03 ~]# masterha_check_repl -conf=/etc/mha_master/mha.cnf

重新启动

nohup masterha_manager -conf=/etc/mha_master/mha.cnf &> /etc/mha_master/manager.log &

最新文章

  1. 动态拼接linq 使用Expression构造动态linq语句
  2. zju 1002
  3. 合并excel-MergeExcel
  4. vps主机修改系统远程端口号/添加防火墙
  5. 编译hadoop遇到maven timeout
  6. #error和#line实例
  7. bzoj1027 [JSOI2007]合金
  8. matlab cross 3*1 向量叉乘
  9. 安装Windows Metasploit Framework
  10. Android sqlite cursor的遍历
  11. Set up JBPM5.4 Final Installer to use MS SQL Server 2008 using JTDS(转)
  12. ios 添加通用断点定位到异常点
  13. 运用linq查找所有重复的元素
  14. Android APK安装包瘦身[转]
  15. FreeMarker的模板文件语法
  16. The Balance(母函数)
  17. python编写网络抓包分析脚本
  18. ABP+AdminLTE+Bootstrap Table权限管理系统第八节--ABP错误机制及AbpSession相关
  19. [3.24校内训练赛by hzwer]
  20. C# Json.Net解析实例

热门文章

  1. Topcoder SRM 657DIV2
  2. 2017多校Round7(hdu6120~hdu6132)
  3. java基础语法1
  4. Spring中使用构造函数实现Beans自动装配
  5. SQL Server 2008 R2 安装时提示“Reporting Services目录数据库文件存在”
  6. 从头开始学Android之(二)—— Android版本
  7. Linux系统启动流程分析
  8. hdu1181 dfs搜索之变形课
  9. 关键路径(AOE)---《数据结构》严蔚敏
  10. Pulse-code modulation