MySQL MHA详细搭建过程

环境:

用3台服务器搭建MySQL MHA

主节点:192.168.157.128   CentOS 7.6

数据库:mysql-5.7.27-linux-glibc2.12-x86_64

从节点:192.168.157.129   CentOS 7.6

数据库:mysql-5.7.27-linux-glibc2.12-x86_64

管理节点:192.168.157.130   CentOS 7.6

数据库:mysql-5.7.27-linux-glibc2.12-x86_64


1、3台服务器都安装操作系统 CentOS 7.6


2、 MySQL  安装以及主从设置


三台机器都要做:

关闭防火墙:

systemctl stop firewalld.service

systemctl disable firewalld.service

systemctl status firewalld.service


#关闭selinux

setenforce 0

PS:

临时关闭:

[root@localhost ~]# getenforce

Enforcing

[root@localhost ~]# setenforce 0

[root@localhost ~]# getenforce

Permissive

永久关闭:

[root@localhost ~]# vi /etc/sysconfig/selinux

SELINUX=enforcing 改为 SELINUX=disabled

重启服务reboot


#删除预装mysql

rpm -qa|grep mariadb

rpm -e --nodeps mariadb-libs-5.5.60-1.el7_5.x86_64


#解压

tar zxvf mysql-5.7.27-linux-glibc2.12-x86_64.tar.gz  -C  /opt

#改名

mv mysql-5.7.27-linux-glibc2.12-x86_64 mysql

#新建mysql用户

useradd mysql

passwd mysql

#

#初始化

mkdir -p /opt/mysql/data

chown -R mysql:mysql /opt/

chown -R mysql:mysql /opt/


#建立相关文件夹

mkdir -p /opt/mysql/tmp

mkdir -p /opt/mysql/log

#更改文件夹权限

chown -R mysql:mysql /opt/mysql

#创建mysql.err文件

[root@mha02 opt]# cd mysql/log

[root@mha02 log]# ll

total 0

[root@mha02 log]# touch mysql.err

[root@mha02 log]# chown -R mysql:mysql mysql.err



#初始化数据库

mysql/bin/mysqld --initialize --user=mysql --basedir=/opt/mysql/ --datadir=/opt/mysql/data/


#简单配置

ln -s /opt/mysql/bin/mysql /usr/bin

ln -s /opt/mysql/bin/mysqladmin /usr/bin

ln -s /opt/mysql/bin/mysqldump /usr/bin


#mysql配置文件,每个服务器的server-id要不同

vi /etc/my.cnf

[client]

port=3306

socket=/opt/mysql/tmp/mysql.sock

[mysqld]

user=mysql

datadir=/opt/mysql/data

basedir=/opt/mysql

socket=/opt/mysql/tmp/mysql.sock

log-error=/opt/mysql/log/mysql.err

pid-file=/opt/mysql/tmp/mysqld.pid

#  id每台机器要不同

server-id = 186

#做双主时的设置,保证另一个主库操作能写入

log_slave_updates

#从库不会跟着主库重启

skip-slave-start

#开启gtid模式,5.7特有

gtid_mode = on

enforce_gtid_consistency = 1

log_slave_updates = 1

#半同步复制模式

plugin_load = "rpl_semi_sync_master=semisync_master.so;rpl_semi_sync_slave=semisync_slave.so"

loose_rpl_semi_sync_master_enabled = 1

loose_rpl_semi_sync_slave_enabled = 1

loose_rpl_semi_sync_master_timeout = 5000

#指定binlog与relay地址

log-bin   = /opt/mysql/log/mysql-bin

relay-log = /opt/mysql/log/mysql-relay-bin

#不要同步哪些库,较好的写法

replicate-wild-ignore-table=mysql.%

replicate-wild-ignore-table=test.%

replicate-wild-ignore-table=information_schema.%



#开启数据库

/opt/mysql/bin/mysqld_safe --defaults-file=/etc/my.cnf &



#登录数据库,修改root密码

mysql -p

之前初始化的密码

mysql> alter user root@'localhost' identified by '123456';

mysql>flush privileges;



增加root远程登录用户:

mysql> create user root@'%' identified by '123456';

Query OK, 0 rows affected (0.01 sec)

mysql> grant all privileges on *.* to root@'%';

mysql> flush privileges;



关闭MySQL服务:

[root@mha01 bin]# mysqladmin -uroot -p -S /opt/mysql/tmp/mysql.sock shutdown

开启MySQL服务:

/opt/mysql/bin/mysqld_safe --defaults-file=/etc/my.cnf &



同样在其余两个服务器上安装MySQL服务。


#登录mysql,在三个mysql中都配置账号,注意,不能把mysql库作为binlog复制库,否则新建的slave账号会报错

#创建slave账号

mysql> grant replication slave,replication client on *.* to 'repl'@'%' identified by '123456';

#创建mha管理账号

mysql> grant all on *.* to 'monitor'@'%' identified by '123456';

#在slave节点上执行

mysql> set global read_only=1;

#由于从库随时会提升成主库,不能写在配置文件里

#MHA需要通过relay-log去校验slave是否数据读写一致,不要写进配置文件,所有mysql节点执行

mysql>set global relay_log_purge=0;

#设置主从

1、主库查看master

mysql> show master status;

+------------------+----------+--------------+------------------+------------------------------------------+

| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                        |

+------------------+----------+--------------+------------------+------------------------------------------+

| mysql-bin.000002 |      932 |              |                  | 58d16735-bdae-11e9-b8d3-000c29f97b79:1-8 |

+------------------+----------+--------------+------------------+------------------------------------------+

1 row in set (0.00 sec)

2、slave库执行

mysql> change master to  

master_host='192.168.157.128',

master_user='repl',

master_password='123456',

master_log_file='mysql-bin.000002',

master_log_pos=932;

用GTID启动slave:

mysql>change master to

master_host='192.168.157.128',

master_user='repl',

master_password='123456',

master_auto_position=1;

mysql> start slave;

Query OK, 0 rows affected (0.02 sec)

mysql> show slave status\G;

             Relay_Master_Log_File: mysql-bin.000003

             Slave_IO_Running: Yes

             Slave_SQL_Running: Yes

看到两个YES,即代表主从成功。


3、搭建MHA


三台主机ssh互信

注意:三台主机都要做,并且要本机对本机的SSH认证

#因为mha需要manager对自己ssh免密登录

ssh-keygen -t rsa

ssh-copy-id -i ~/.ssh/id_rsa.pub [email protected]

ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.157.129

ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.157.130



MHA安装配置:

三台机器都要做:

在/opt目录下安装:

在所有节点安装MHA node所需的perl模块,如下:

#CentOS 6 下载点

rpm -ivh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm

#CentOS 7 下载点

rpm -ivh http://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm

#安装所需控件

#yum install -y perl-DBD-MySQL perl-Config-Tiny perl-Log-Dispatch perl-Parallel-ForkManager perl-Time-HiRes  

yum install -y perl-DBD-MySQL perl-Config-Tiny perl-Log-Dispatch perl-Parallel-ForkManager perl-YAML-Tiny perl-PAR-Dist perl-Module-ScanDeps perl-Module-CoreList perl-Module-Build perl-CPAN perl-CPANPLUS perl-File-Remove perl-Module-Install

#下载node和manager软件

# node git 地址:https://github.com/yoshinorim/mha4mysql-node

# manager git 地址:https://github.com/yoshinorim/mha4mysql-manager

# node 所有机器都要安装

# manager 只需要管理节点安装

yum -y install git

git clone https://github.com/yoshinorim/mha4mysql-node.git

#管理节点安装

git clone https://github.com/yoshinorim/mha4mysql-manager.git

安装MHA

cd /opt/mha4mysql-node

perl Makefile.PL

make && make install

cd /opt/mha4mysql-manager

perl Makefile.PL

make && make install

注意:在perl Makefile.PL时,可能会出现类似Can't locate inc/Module/XXX.pm in @INC的报错

          这是由于缺少组件造成的,只需要安装相应附件

          例: yum -y install perl-Module-XXX  一般有对应的名字插件,安装就好

#node方面的都已经配好了,然后是manager节点的操作

配置 Manager 节点,以下步骤都是Manager节点操作

#新建MHA配置文件

mkdir /var/log/mha/app1 -p

touch /var/log/mha/app1/manager.log

vi /etc/masterha.cnf

[server default]

#监控用户

user=monitor

password=123456

#ssh 用户

ssh_user=root

#slave 用户

repl_user=repl

repl_password=123456

#ping 三次不通判断失联

ping_interval=3

#使用其他主机去ping,判断是否主机本身故障

secondary_check_script=masterha_secondary_check -s 192.168.157.128 -s 192.168.157.129 -s 192.168.157.130

#相关脚本位置,都要自建,默认是没有的

master_ip_failover_script=/usr/local/bin/master_ip_failover

master_ip_online_change_script= /usr/local/bin/master_ip_online_change

report_script=/usr/local/bin/send_report

#指定MHA日志目录

manager_workdir=/var/log/mha/app1

manager_log=/var/log/mha/app1/manager.log

#指定bin-log位置

master_binlog_dir=/opt/mysql/log/

remote_workdir=/var/log/mha/mysqltmp

[server1]

hostname=192.168.157.128

port=3306

[server2]

hostname=192.168.157.129

port=3306

#是否无视落后进度让他成为master

candidate_master=1

check_repl_delay=0

[server3]

hostname=192.168.157.130

#永远不会成为master。多用于manager

no_master=1

port=3306



#配置VIP

#为了防止脑裂发生,推荐生产环境采用脚本的方式来管理虚拟 ip,而不是使用 keepalived来完成


vi /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

);

#定义VIP变量

#此处修改VIP地址,预先选择的VIP地址

my $vip = '192.168.157.197/24';

my $key = '1';

#修改ifconfig之后的网卡名,其他地方都不要改动

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 "\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 \"`;

}

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\n";

}


郑州同济医院:http://jbk.39.net/yiyuanzaixian/zztjyy/

#配置报警邮件脚本

#安装邮件

yum install mailx -y

vi /etc/mail.rc

#修改mail配置文件,在配置文件最后新增

#邮箱地址

set from=ywzj_002@163.com

#邮箱的smtp地址

set smtp=smtp.163.com

#邮箱的用户名

set smtp-auth-user=ywzj_002

#这个并非邮箱密码,而是授权码

set smtp-auth-password=pousheng123

set smtp-auth=login

vi /usr/local/bin/send_report

#!/bin/bash

source /root/.bash_profile

orig_master_host=`echo "$1" | awk -F = '{print $2}'`

new_master_host=`echo "$2" | awk -F = '{print $2}'`

new_slave_hosts=`echo "$3" | awk -F = '{print $2}'`

subject=`echo "$4" | awk -F = '{print $2}'`

body=`echo "$5" | awk -F = '{print $2}'`

email="[email protected]"

tac /var/log/mha/app1/manager.log | sed -n 2p | grep 'successfully' > /dev/null

if [ $? -eq 0 ]

       then

       messages=`echo -e "MHA $subject 主从切换成功\n master:$orig_master_host -->

$new_master_host \n $body \n 当前从库:$new_slave_hosts"`

       echo "$messages" | mail -s "Mysql 实例宕掉,MHA $subject 切换成功" $email >

>/tmp/mailx.log 2>&1

       else

       messages=`echo -e "MHA $subject 主从切换失败\n master:$orig_master_host -->

$new_master_host \n $body" `

       echo "$messages" | mail -s ""Mysql 实例宕掉,MHA $subject 切换失败"" $email

>>/tmp/mailx.log 2>&1

fi


#配置VIP更换脚本

vi /usr/local/bin/master_ip_online_change

#预先选择的VIP地址

vip=`echo '192.168.157.197/24'`

key=`echo '1'`

command=`echo "$1" | awk -F = '{print $2}'`

orig_master_host=`echo "$2" | awk -F = '{print $2}'`

new_master_host=`echo "$7" | awk -F = '{print $2}'`

orig_master_ssh_user=`echo "${12}" | awk -F = '{print $2}'`

new_master_ssh_user=`echo "${13}" | awk -F = '{print $2}'`

#修改网卡名称

stop_vip=`echo "ssh root@$orig_master_host /usr/sbin/ifconfig ens33:$key down"`

start_vip=`echo "ssh root@$new_master_host /usr/sbin/ifconfig ens33:$key $vip"`

if [ $command = 'stop' ]

 then

   echo -e "\n\n\n****************************\n"

   echo -e "Disabled thi VIP - $vip on old master: $orig_master_host \n"

   $stop_vip

   if [ $? -eq 0 ]

     then

       echo "Disabled the VIP successfully"

     else

       echo "Disabled the VIP failed"

   fi

   echo -e "***************************\n\n\n"

 fi

       if [ $command = 'start' -o $command = 'status' ]

 then

   echo -e "\n\n\n*************************\n"

   echo -e "Enabling the VIP - $vip on new master: $new_master_host \n"

   $start_vip

   if [ $? -eq 0 ]

     then

       echo "Enabled the VIP successfully"

     else

       echo "Enabled the VIP failed"

   fi

   echo -e "***************************\n\n\n"

fi

#赋予脚本权限

#*代表之前创建的三个脚本

chmod 555 /usr/local/bin/*

chmod 555 /usr/local/bin/master_ip_failover

chmod 555 /usr/local/bin/master_ip_online_change

chmod 555 /usr/local/bin/send_report

#测试MHA设置是否正确

masterha_check_repl --conf=/etc/masterha.cnf



。。。

MySQL Replication Health is OK.

最后 显示OK,才算正常,否则就要看报错信息,按照之前的操作配置,基本不会有错误。



#在主库,而不是Manager管理口,配置VIP到网口

/usr/sbin/ifconfig ens33:1 192.168.157.197/24

注意:如果是最小化安装,需yum ifconfig

          yum -y install net-tools



#在Manager节点操作

#启动MHA

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

#检查状态

[root@mha03 bin]# masterha_check_status --conf=/etc/masterha.cnf

masterha (pid:15546) is running(0:PING_OK), master:192.168.157.128

#显示OK则正常



测试切换功能以及主库宕机上线:


1、在线切换

#MHA 在线切换是 MHA 除了自动监控切换换提供的另外一种方式,多用于诸如硬件升级,MySQL 数据库迁移等等。该方式提供快速切换和优雅的阻塞写入,无需关闭原有服务器,整个切换过程在 0.5-2s 的时间左右,大大减少了停机时间

注意:需要关闭mha监控才能运行

          A、老master上的vip已经正确生效了

          B、各个salve节点数据库的sql_IO和sql_sql进程都正常(即YES)

                    show slave status\G;

          C、MHA脚本不能运行,若已处于监控状态,需要停掉它

                    masterha_stop --conf=/etc/masterha.cnf

#执行切换

#需要填写新的master的IP

masterha_master_switch --conf=/etc/masterha.cnf --master_state=alive --new_master_host=192.168.157.129 --orig_master_is_new_slave --running_updates_limit=10000 --interactive=0

masterha_master_switch --conf=/etc/masterha.cnf --master_state=alive --new_master_host=192.168.157.128 --orig_master_is_new_slave --running_updates_limit=10000 --interactive=0

#MHA 在线切换基本步骤:

    a、检测 MHA 配置置及确认当前 master

    b、决定新的 master

    c、阻塞写入到当前 master

    d、等待所有从服务器与现有 master 完成同步

    e、在新 master 授予写权限,以及并行切换从库

    f、重置原 master 为新 master 的 slave

    g、在线切换不会删除/etc/masterha.cnf 配置文件中原来老的 master 配置

注意:如果手动切换后,原来的配置如果想直接运行,需要在配置文件中将master的地址改成新的IP,原Master主机的IP写到slave中


2、自动切换

    第一:要实现自动 Failover,必须先启动 MHA Manager,否则无法自动切换

    A、杀掉主库 mysql 进程,模拟主库发生故障,进行自动 failover 操作

    B、看 MHA 切换日志,了解整个切换过程

        tailf  /var/log/mha/app1/manager.log

    第二:从上面的输出可以看出整个 MHA 的切换过程,共包括以下的步骤:

    1).配置文件检查阶段,这个阶段会检查整个集群配置文件配置

    2).宕机的 master 处理,这个阶段包括虚拟 ip 摘除操作,主机关机操作(由于没有定义power_manager脚本,不会关机)

    3).复制 dead maste 和最新 slave 相差的 relay log,并保存到 MHA Manger 具体的目录下

    4).识别含有最新更新的 slave

    5).应用从 master 保存的二进制日志事件(binlog events)(这点信息对于将故障master修复后加入集群很重要)

    6).提升一个 slave 为新的 master 进行复制

    7).使其他的 slave 连接新的 master 进行复制

    第三:切换完成后,关注如下变化:

    1、vip 自动从原来的 master 切换到新的 master,同时,manager 节点的监控进程自动退出。

    2、在日志目录(/var/log/mha/app1)产生一个 app1.failover.complete 文件

   3、/etc/mha/app1.cnf 配置文件中原来老的 master 配置被删除。


4、切换一次后,MHA监控程序会stop,需要重新修改配置文件后再次重启

#会发现此时192.168.157.129从库已经提升为主库,并且MHA Manager已停止运行。

重要:将主库重新恢复加入到队列的操作

1)、修改 manager 配置文件(只针对自动切换的,在线切换不会删除配置)

    #将如下内容添加到/etc/masterha.cnf中

    [server1]

    hostname=192.168.157.128

    candidate_master=1

   port=3306

    master_binlog_dir=/opt/mysql/log/

#由于之前主库宕机后,MHA会自动将配置文件内宕机的主库信息删除

#主库恢复如需重新加入,需要在配置文件新增原主库信息,并作为从库加入

2)、修复老的 master,然后设置为 slave

    从自动切换时刻的 MHA 日志上可以发现类似如下信息:

    #意思是说,如果 Master 主机修复好了,可以在修复好后的 Master 上执行 CHANGE MASTER操作,作为新的 slave 库。

[root@mha03 app1]# cat  manager.log|grep CHANGE

[root@mha03 app1]# pwd

/var/log/mha/app1

#GTID没有开启

    Sat May 27 14:59:17 2017 - [info] All other slaves should start replication from here. Statement

    should be: CHANGE MASTER TO MASTER_HOST='10.0.40.187', MASTER_PORT=3306,

    MASTER_LOG_FILE='mysql-bin.000009', MASTER_LOG_POS=120, MASTER_USER='repl',

    MASTER_PASSWORD='xxx';

 #GTID开启

    Sat May 19 05:00:48 2018 - [info]  All other slaves should start replication from here. Statement should be: CHANGE MASTER TO MASTER_HOST='10.0.40.187', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='xxx';

Thu Aug 15 15:31:18 2019 - [info]  All other slaves should start replication from here. Statement should be: CHANGE MASTER TO MASTER_HOST='192.168.157.129', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='xxx';

Thu Aug 15 15:31:19 2019 - [info]  Executed CHANGE MASTER.

    

在老的 master 执行如下命令:(具体执行哪条,根据上面输出来确定,区别是一个有日志的定位,一个是自动定位)

   #GTID没有开启,按照日志的log-file和log-pos填写

    mysql> change master to master_host='10.0.40.187',master_user='repl',master_password='123456',master_log_file='mysql-bin.0000124',master_log_pos=120;

   #GTID开启,只能使用MASTER_AUTO_POSITION=1,否则报错

    mysql> change master to master_host='10.0.40.187',master_user='repl',master_password='123456',MASTER_AUTO_POSITION=1;

CHANGE MASTER TO MASTER_HOST='192.168.157.129', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='123456';

mysql> CHANGE MASTER TO MASTER_HOST='192.168.157.129', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='123456';

Query OK, 0 rows affected, 2 warnings (0.02 sec)

mysql> start slave;

Query OK, 0 rows affected (0.01 sec)

mysql> show slave status\G;


 #这样,数据就开始同步到老的 master 上了。此时老的 master 已经重新加入集群,变成 mha集群中的一个 slave 角色了。


(3)、在 manger 节点上重新启动监控进程

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


Done.


猜你喜欢

转载自blog.51cto.com/14510269/2431366