8.MHA高可用集群+Atlas读写分离

所有软件下载地址:链接:https://share.weiyun.com/QEgshNc8 密码:hg8mnz

MHA修复流程说明

(1) MHA通过masterha_manger脚本启动MHA的功能.
(2) 在manager启动之前,会自动检查ssh互信(masterha_check_ssh)和主从状态(masterha_check_repl)
(3) MHA-manager 通过 masterha_master_monitor脚本(每隔ping_interval秒)
(4) masterha_master_monitor探测主库3次无心跳之后,就认为主库宕机了.
(5) 进行选主过程
	算法一: 
	读取配置文件中是否有强制选主的参数?
	candidate_master=1     #强制这台机器为主
	check_repl_delay=0     #不管这台机器和主库相差多少数据,都忽略
	算法二:
	自动判断所有从库的日志量.将最接近主库数据的从库作为新主.
	算法三:
	按照配置文件先后顺序的进行选新主.
(6) 数据补偿 
        判断主库SSH的连通性
        情况一: SSH能连
        调用 save_binary_logs脚本,立即保存缺失部分的binlog到各个从节点,恢复
        情况二: SSH无法连接
        调用 apply_diff_relay_logs 脚本,计算从库的relaylog的差异,恢复到2号从库
        情况三:提供额外的binlog-server
(7) 解除从库身份
(8) 剩余从库和新主库构建主从关系
(9) 应用透明  @@
(10) 故障节点自愈(待开发...)@@
(11) 故障提醒@
(12) 手动修复故障主库,并将故障主库身份转换成从库,修改MHA管理端配置文件,修改binlog server指向的地址

MHA搭建环境前提条件
1.最少三台MySQL服务器,1主2从。
2.MHA管理端不能放在MySQL主服务器上。
3.MHA为一次性环境,故障处理完毕后需要手动调整
4.在搭建MHA之前,三台数据库需要同时有MHA管理用户和mysql复制用户
5.MHA可以同时管理多个不同的mysql集群,启动MHA管理端时指定不同的配置文件即可

开始搭建

  • 1.准备3三台mysql服务器,搭建好主从环境,所有节点都需要开启bin_log,额外准备一台MHA管理服务器,一共四台服务器
  • 2.所有Mysql3台节点创建MHA需要用到的软连接,源节点根据软件安装情况更改,目标节点必须在/usr/bin下(就算mysql命令在环境变量中也需要链接到该目录下)
ln -s /application/mysql/bin/mysqlbinlog    /usr/bin/mysqlbinlog
ln -s /application/mysql/bin/mysql          /usr/bin/mysql
  • 3.所有主机进行免密认证
# ssh-keygen
# ssh-copy-id

#各节点验证,避免出现输入yes的情况
  • 4.在mysql主库创建MHA用户(这个用户在三台mysql服务器上都需要创建,如果提前做好了主从,只需要在主库创建这个用户)
mysql> grant all privileges on *.* to mha@'%' identified by 'mha';
  • 5.所有节点安装节点软件包(四个节点都装)
#安装依赖
yum install perl-DBD-MySQL -y
#安装节点包
rpm -ivh mha4mysql-node-0.56-0.el6.noarch.rpm
  • 6.MHA管理节点安装管理软件(只有MHA管理节点安装)
#安装依赖
yum install -y perl-Config-Tiny epel-release perl-Log-Dispatch perl-Parallel-ForkManager perl-Time-HiRes
#安装管理软件
rpm -ivh mha4mysql-manager-0.56-0.el6.noarch.rpm
  • 7.创建MHA节点配置文件(只有MHA管理节点需要这个配置文件)
#创建配置文件目录
mkdir -p /etc/mha
#创建日志目录,可以同时管理多个节点
mkdir -p /var/log/mha/app1

#编辑mha配置文件,针对app1集群的配置
cat > /etc/mha/app1.cnf <<EOF
[server default]
#日志文件名称,程序运行日志,排错都在这里面看
manager_log=/var/log/mha/app1/manager        
#工作目录
manager_workdir=/var/log/mha/app1            
#mysql数据库存放binlog位置,mha会监控这个日志
master_binlog_dir=/var/lib/mysql       
#mha管理用户名
user=mha        
#mha管理用户密码                           
password=mha    
#心跳检测间隔时间                           
ping_interval=2
#mysql复制用户密码
repl_password=123
#MySQL复制用户名
repl_user=repl
#ssh用户
ssh_user=root    
#高可用IP漂移脚本,下面会给出配置 
master_ip_failover_script=/usr/local/bin/master_ip_failover                          
#故障切换完成后发送邮件的脚本
report_script=/usr/local/bin/send

#管理的mysql实例位置,故障选主时,从上至下顺序选主
[server1]                                   
hostname=192.168.2.3
port=3306                                  
[server2]            
hostname=192.168.2.4
port=3306
[server3]
hostname=192.168.2.5
port=3306

#数据补偿服务器,强制不能成为主库,二进制日志保存路径不能和mysql服务器二进制日志保存路径相同
[binlog1]
no_master=1
hostname=192.168.2.5
master_binlog_dir=/data/mysql/binlog
EOF
    • 7.1主从切换脚本

这个脚本由perl语言编写,只需要对应更改下面内容,脚本文件放在MHA管理端配置文件master_ip_failover_script=/usr/local/bin/master_ip_failover对应位置,需要添加+x执行权限

my $vip = '192.168.3.88/24';     #高可用出来的VIP
my $key = '1';             #子网卡序号,例如eth0:1
my $ssh_start_vip = "/sbin/ifconfig ens33:$key $vip";    #开启vip,对应改网卡名
my $ssh_stop_vip = "/sbin/ifconfig ens33:$key down";  #关闭vip,对应改网卡名

[root@nginx ~]# 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 = '192.168.3.88/24';
my $key = '1';
my $ssh_start_vip = "/sbin/ifconfig ens33:$key $vip";
my $ssh_stop_vip = "/sbin/ifconfig ens33:$key down";

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 "

IN SCRIPT TEST====$ssh_stop_vip==$ssh_start_vip===

";

    if ( $command eq "stop" || $command eq "stopssh" ) {

        my $exit_code = 1;
        eval {
            print "Disabling the VIP on old master: $orig_master_host 
";
            &stop_vip();
            $exit_code = 0;
        };
        if ($@) {
            warn "Got Error: $@
";
            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 
";
            &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 
";
        exit 0;
    }
    else {
        &usage();
        exit 1;
    }
}

sub start_vip() {
    `ssh $ssh_user@$new_master_host " $ssh_start_vip "`;
}
sub stop_vip() {
     return 0  unless  ($ssh_user);
    `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
";
}
    • 7.2故障修复后发送邮件程序

三个文件如下,放在服务器上之后都需要有执行权限,脚本必须放在/usr/local/bin下

只需要修改testpl配置文件中的内容,MHA管理端只会调用send脚本,后续操作都有send脚本自行操作。(文件需要对应修改邮箱密码信息)

[root@nginx ~]# vim /usr/local/bin/testpl 
#!/bin/bash
/usr/local/bin/sendEmail -o tls=no -f 发送邮件邮箱@126.com -t 接收邮件邮箱@qq.com -s smtp.126.com:25 -xu 发送邮箱的用户 -xp 发送邮箱的认证码 -u "MHA Waring" -m "YOUR MHA MAY BE FAILOVER" &>/tmp/sendmail.log  
    • 7.3数据补偿服务器
[binlog1]
no_master=1
hostname=192.168.2.5
master_binlog_dir=/data/mysql/binlog

MHA管理端的这三条配置是binlog-server的配置,需要在对应服务器上创建该目录,并手动拉取数据。
MHA完成故障切换后,拉取二进制日志的主机需要重新配置mysql主库地址

#创建必要目录
mkdir -p /data/mysql/binlog
chown -R mysql.mysql /data/*

#手动拉取主库binlog日志
cd /data/mysql/binlog    #必须进入到自己创建好的目录
mysqlbinlog  -R --host=10.0.0.51 --user=mha --password=mha --raw  --stop-never mysql-bin.000001 &

#注意:拉取日志的起点 mysql-bin.000001,需要按照目前主库正在使用的binlog为起点.
  • 8.MHA管理端进行状态检查(只有MHA管理端有这个命令)
#检查主机ssh状况
masterha_check_ssh  --conf=/etc/mha/app1.cnf 
#出现下面状态代表ssh状态正常
#[info] All SSH connection tests passed successfully.

#检查mysql复制状况
masterha_check_repl  --conf=/etc/mha/app1.cnf 
#出现下面状态代表mysql复制状态正常
#MySQL Replication Health is OK.
  • 9.第一次开启MHA前,需要手动在mysql主库服务器上添加VIP,后续漂移VIP是由MHA自动完成
/sbin/ifconfig ens33:1 192.168.2.88/24 up 
  • 10.检查顺利完成后,MHA节点开启管理端(MHA管理程序会以守护进程运行)
nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover  &> /var/log/mha/app1/manager.log  &

#--conf:指定配置文件
#--remove_dead_master_conf:mysql主库故障时,MHA自动从配置文件中移除坏掉的master
#--ignore_last_failover:MHA切换主从后的8个小时内,如果mysql主库再次出现故障,MHA不会进行切换,加上ignore_last_failover,MHA不会管上一次切换是什么时候,只要mysql主库出现故障,就会切换
  • 11.查看MHA状态
masterha_check_status --conf=/etc/mha/app1.cnf
#出现如下状态代表正常
#app1 (pid:8050) is running(0:PING_OK), master:192.168.2.3
  • 12.MHA日志
#MHA的工作日志,下面是个日志文件,不是目录
manager_log=/var/log/mha/app1/manager
  • 13.其他命令
masterha_manger             启动MHA 
masterha_check_ssh      	检查MHA的SSH配置状况 
masterha_check_repl         检查MySQL复制状况 
masterha_master_monitor     检测master是否宕机 
masterha_check_status       检测当前MHA运行状态 
masterha_master_switch  	控制故障转移(自动或者手动)
masterha_conf_host      	添加或删除配置的server信息 
  • 14.其他参数
candidate_master=1  #强制选主
check_repl_delay=0   #不管和主库相差多少数据,都忽略  

模拟故障

  • 停掉mysql主库
systemctl stop mysqld
  • 查看MHA日志信息
    1.原主库挂掉。
    2.其中一台从库晋升为主库
    3.另一台从库复制到新的主库上
    4.成功发送邮件
----- Failover Report -----

app1: MySQL Master failover 192.168.3.156(192.168.3.156:3306) to 192.168.3.157(192.168.3.157:3306) succeeded

Master 192.168.3.156(192.168.3.156:3306) is down!

Check MHA Manager logs at nginx:/var/log/mha/app1/manager for details.

Started automated(non-interactive) failover.
Invalidated master IP address on 192.168.3.156(192.168.3.156:3306)
The latest slave 192.168.3.157(192.168.3.157:3306) has all relay logs for recovery.
Selected 192.168.3.157(192.168.3.157:3306) as a new master.
192.168.3.157(192.168.3.157:3306): OK: Applying all logs succeeded.
192.168.3.157(192.168.3.157:3306): OK: Activated master IP address.
192.168.3.161(192.168.3.161:3306): This host has the latest relay log events.
Generating relay diff files from the latest slave succeeded.
192.168.3.161(192.168.3.161:3306): OK: Applying all logs succeeded. Slave started, replicating from 192.168.3.157(192.168.3.157:3306)
192.168.3.157(192.168.3.157:3306): Resetting slave info succeeded.
Master failover to 192.168.3.157(192.168.3.157:3306) completed successfully.
Tue May 12 13:26:13 2020 - [info] Sending mail..
  • 查看VIP漂移情况:发现VIP顺利漂移到新的主库
  • 查看binlog-server:发现复制二进制日志的守护进程已经自动结束
  • 查看MHA管理端配置文件信息:发现原mysql主库配置已经被移除

故障修复  

  • 1.查看原主库上的VIP是否已经漂移到新主库上
  • 2.更改原主库为从
    • 查看MHA日志文件中,有一句是改主命令
[root@nginx ~]# grep CHANGE /var/log/mha/app1/manager
Tue May 12 13:26:10 2020 - [info]  All other slaves should start replication from here. Statement should be: CHANGE MASTER TO MASTER_HOST='192.168.3.157', MASTER_PORT=3306, MASTER_LOG_FILE='mysql2-binlog.000006', MASTER_LOG_POS=154, MASTER_USER='repl', MASTER_PASSWORD='xxx';
Tue May 12 13:26:12 2020 - [info]  Executed CHANGE MASTER.
    • 启动原主库,在原主库上执行CHANGE MASTER TO命令到新的主库,复制账号的密码要对应修改
mysql> CHANGE MASTER TO MASTER_HOST='192.168.3.157', MASTER_PORT=3306, MASTER_LOG_FILE='mysql2-binlog.000006', MASTER_LOG_POS=154, MASTER_USER='repl', MASTER_PASSWORD='xxx';
mysql> START SLAVE;
  • 3.恢复MHA管理端配置文件(将主库迁移时,自动删除的配置补上)
[server1]
hostname=192.168.2.3
port=3306
[server2]
hostname=192.168.2.4
port=3306
[server3]
hostname=192.168.2.5
port=3306
  • 4.清理binlog-server上原有的二进制日志,并重新复制新的主库二进制日志。二进制日志名称可以在新主库上执行SHOW MASTER STATUS查看
cd /data/mysql/binlog    
rm -rf /data/mysql/binlog/*
mysqlbinlog  -R --host=192.168.2.4 --user=mha --password=mha --raw  --stop-never mysql-bin.000001 &
  • 5.重新启动MHA管理端,并查看服务状态
[root@nginx ~]# nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover  &>> /var/log/mha/app1/manager.log  &
[root@nginx ~]# masterha_check_status --conf /etc/mha/app1.cnf   
app1 (pid:19214) is running(0:PING_OK), master:192.168.2.4

  


 Atlas读写分离

  • 安装atlas软件包
rpm -ivh Atlas-2.2.1.el6.x86_64.rpm
  • 修改配置文件,默认配置文件在/usr/local/mysql-proxy/conf下,配置文件中有详细的中文注释。
[mysql-proxy]
#管理接口的用户名
admin-username = user
#管理接口的密码
admin-password = pwd
#Atlas后端连接的MySQL主库的IP和端口,可设置多项,用逗号分隔
proxy-backend-addresses = 10.0.0.55:3306
#Atlas后端连接的MySQL从库的IP和端口,@后面的数字代表权重,用来作负载均衡,若省略则默认为1,可设置多项,用逗号分隔
proxy-read-only-backend-addresses = 10.0.0.51:3306@1,10.0.0.53:3306@2
#用户名与其对应的加密过的MySQL密码,密码使用PREFIX/bin目录下的加密程序encrypt加密,下行的user1和user2为示例,将其替换为你的MySQL的用户名和加密密码!
pwds = repl:3yb5jEku5h4=,mha:O2jBXONX098=
#设置Atlas的运行方式,设为true时为守护进程方式,设为false时为前台方式,一般开发调试时设为false,线上运行时设为true,true后面不能有空格。
daemon = true
#设置Atlas的运行方式,设为true时Atlas会启动两个进程,一个为monitor,一个为worker,monitor在worker意外退出后会自动将其重启,设为false时只有worker,没有monitor,一般开发调试时设为false,线上运行时设为true,true后面不能有空格。
keepalive = true
#工作线程数,对Atlas的性能有很大影响,可根据情况适当设置
event-threads = 8
#日志级别,分为message、warning、critical、error、debug五个级别
log-level = message
#日志存放的路径
log-path = /usr/local/mysql-proxy/log
#SQL日志的开关,可设置为OFF、ON、REALTIME,OFF代表不记录SQL日志,ON代表记录SQL日志,REALTIME代表记录SQL日志且实时写入磁盘,默认为OFF
sql-log=ON
#应用程序访问的端口
proxy-address = 0.0.0.0:33060
#管理员访问的端口
admin-address = 0.0.0.0:2345
#默认字符集,设置该项后客户端不再需要执行SET NAMES语句
charset=utf8
#允许连接Atlas的客户端的IP,可以是精确IP,也可以是IP段,以逗号分隔,若不设置该项则允许所有IP连接,否则只允许列表中的IP连接
#client-ips = 127.0.0.1, 192.168.1
  • 启动atlas,启动命令中的test是根据配置文件名称来的。atlas可以有多个实例,根据配置文件来区别启动  
[root@nginx mysql-proxy]# /usr/local/mysql-proxy/bin/mysql-proxyd test start
OK: MySQL-Proxy of test is started
  • 测试atlas读写分离功能,这里连接的就是atlas的代理端口
mysql -umha -pmha  -h 10.0.0.53 -P 33060
#测试读操作:会发现语句会负载均衡到两台从库上 
mysql> SELECT @@server_id;
+-------------+
| @@server_id |
+-------------+
|           1 |
+-------------+
1 row in set (0.02 sec)

mysql> SELECT @@server_id;
+-------------+
| @@server_id |
+-------------+
|           3 |
+-------------+
1 row in set (0.01 sec)

#测试写操作:会发现写操作在主库上
mysql> begin;select @@server_id;commit;
Query OK, 0 rows affected (0.01 sec)

+-------------+
| @@server_id |
+-------------+
|           2 |
+-------------+  

Atlas管理端口应用

  • 连接atlas管理端
#用户名、密码和端口都在atlas配置文件中
mysql -uuser -ppwd -h 192.168.1.92 -P 2345
  • 打印帮助信息
MySQL [(none)]> SELECT * FROM HELP;
  • 查看所有后端节点
MySQL [(none)]> SELECT * FROM backends;
+-------------+--------------------+-------+------+
| backend_ndx | address            | state | type |
+-------------+--------------------+-------+------+
|           1 | 192.168.3.88:3306  | up    | rw   |
|           2 | 192.168.3.156:3306 | up    | ro   |
|           3 | 192.168.3.161:3306 | up    | ro   |
+-------------+--------------------+-------+------+
3 rows in set (0.00 sec)
  • 下线一个节点(不是删除),请求就不会到这个后端
MySQL [(none)]> SET OFFLINE 2;
+-------------+--------------------+---------+------+
| backend_ndx | address            | state   | type |
+-------------+--------------------+---------+------+
|           2 | 192.168.3.156:3306 | offline | ro   |
+-------------+--------------------+---------+------+
1 row in set (0.00 sec)
  • 上线一个节点
MySQL [(none)]> SET ONLINE 2;
+-------------+--------------------+---------+------+
| backend_ndx | address            | state   | type |
+-------------+--------------------+---------+------+
|           2 | 192.168.3.156:3306 | unknown | ro   |
+-------------+--------------------+---------+------+
1 row in set (0.00 sec)
  • 添加一个slave节点(读节点)
> add slave 127.0.0.1:3306
  • 删除一个节点
> remove backend 1;
或
> remove client 192.168.1.2
  • 查询后端用户名密码
MySQL [(none)]>  SELECT * FROM pwds;
+----------+--------------+
| username | password     |
+----------+--------------+
| repl     | /iZxz+0GRoA= |
| mha      | /iZxz+0GRoA= |
+----------+--------------+
2 rows in set (0.00 sec)
  • 添加后端mysql服务器用户,注意!在mysql服务器中仍要手动创建对应用户
MySQL [(none)]> ADD PWD lee:123456;
Empty set (0.00 sec)
  • 保存配置到配置文件中,所有命令都是在内存中更改,使用一下命令会保存到配置文件中
MySQL [(none)]> SAVE CONFIG;
Empty set (0.00 sec)

  

  

  

初学linux,每学到一点东西就写一点,如有不对的地方,恳请包涵!
原文地址:https://www.cnblogs.com/forlive/p/12865458.html