MYSQL高可用环境搭建

目录

一、MHA介绍... 2

二、MHA搭建... 3

1.环境准备... 3

2.MHA下载与MySQL安装... 3

3.配置三台服务器基本信息... 6

4.选择主从模式... 7

> 经典主从复制模式... 7

> GTID模式... 8

5.搭建主从环境... 10

6.安装MHA-Node节点... 18

7.安装MHA-Manager管理节点... 20

8.在主库上添加VIP. 27

9.在管理节点启动MHA服务... 28

三、模拟主库故障,故障切换... 28

1.MHA自动切换主库... 28

2.手动切换主库... 30

一、MHA介绍

MHAMaster High Availability)目前在 MySQL 高可用方面是一个相对成熟的解决方案,是一套优秀的作为 MySQL 高可用性环境下故障切换和主从提升的高可用软件。

MySQL 故障切换过程中,MHA 能做到在0~30秒之内自动完成数据库的故障切换操作,并且在进行故障切换的过程中,MHA 能在最大程度上保证数据的一致性,以达到真正意义上的高可用。

该软件由两部分组成:MHA Manager(管理节点)和 MHA Node(数据节点)。MHA Manager 可以单独部署在一台独立的机器上管理多个 master-slave 集群,也可以部署在一台 slave 节点上。MHA Node 运行在每台 MySQL 服务器上,MHA Manager 会定时探测集群中的 master 节点,当 master 出现故障时,它可以自动将最新数据的 slave 提升为新的 master,然后将所有其他的 slave 重新指向新的 master。整个故障转移过程对应用程序完全透明。

MHA 自动故障切换过程中,MHA 试图从宕机的主服务器上保存二进制日志,最大程度的保证数据的不丢失,但这并不总是可行的。例如,如果主服务器硬件故障或无法通过ssh访问,MHA 没法保存二进制日志,只进行故障转移而丢失了最新的数据。使用 MySQL 5.5 的半同步复制,可以大大降低数据丢失的风险。MHA 可以与半同步复制结合起来。如果只有一个 slave 已经收到了最新的二进制日志,MHA 可以将最新的二进制日志应用于其他所有的 slave 服务器上,因此可以保证所有节点的数据一致性。

目前 MHA 主要支持一主多从的架构,要搭建 MHA,要求一个复制集群中必须最少有三台数据库服务器,一主二从,即一台充当 master,一台充当备用 master,另外一台充当从库,因为至少需要三台服务器,出于机器成本的考虑,淘宝也在该基础上进行了改造,淘宝TMHA已经支持一主一从。

MHA原理:

MHA用于维持 MySQL Replication master 库的高可用性,最大的特点是可以修复多个slave上的差异日志,最终使所有slave保持数据一致,然后从中选取一个充当新的 master,并让其他 slave 指向它。

master出现故障时,通过对比 slave 之间的 I/O thread 读取主库的 binlog position 号,选取最接近的slave作为备胎(被选主库),其它从库通过与备胎对比,生成差异的中继日志,在备胎上运用从原来的 master 保存的 binlog,同时将备胎提升为master。最后在其他 slave 上运用相应的差异中继日志,并从新的 master 开始复制。

MHA优点:

故障切换时,自动判断哪个从库与主库离的最近,并切换到该从库

支持binlog server,提高 binlog 的传送效率

结合半同步功能,确保故障切换时数据不丢失

二、MHA搭建

1.环境准备

IP

Hostname

OS Version

Role

192.168.16.18

centos8-min8

CentOS Linux release 8.2.2004

master

192.168.16.19

centos8-min9

CentOS Linux release 8.2.2004

slave1

192.168.16.20

centos8-min10

CentOS Linux release 8.2.2004

slave2+ manager

由于安装MHA-Node过程中发现centos8并不能安装MHA-Node,所以将操作系统重装换成centos7

IP

Hostname

OS Version

Role

192.168.16.21

centos7-min-ha1

CentOS Linux release 7.8.2003

master

192.168.16.22

centos7-min-ha2

CentOS Linux release 7.8.2003

slave1

192.168.16.23

centos7-min-ha3

CentOS Linux release 7.8.2003

slave2+ manager

2.MHA下载与MySQL安装

>  MHA下载地址

wget https://github.com/yoshinorim/mha4mysql-manager/releases/download/v0.58/mha4mysql-manager-0.58.tar.gz

wget https://github.com/yoshinorim/mha4mysql-node/releases/download/v0.58/mha4mysql-node-0.58.tar.gz

  • MySQL官网下载MYSQL:https://downloads.mysql.com/archives/community/

目前MYSQL官网并未提供redhat8版本的MYSQL产品

centos8-min8:

centos8-min9:

centos8-min10:

  • MySQL安装

使用mysql自动化安装脚本在三台服务器上安装mysql,自动化安装脚本可参考如下:

###采用二进制安装包安装MySQL###
###############################
#!/bin/bash

## The 3 messages you need to update according to your package
dir_package='/opt'
install_package=${dir_package}'/mysql-5.7.24-el7-x86_64.tar.gz'
package_version='mysql-5.7.24'

## The default linux system version is Redhat/CentOS7
clear
echo "=========================================================================="
echo "A tool to auto-compile & install $package_version on Redhat/CentOS7 Linux "
echo "=========================================================================="

## 1. check the integrity of your mysql package
echo ">>Step1: md5sum 验证包的完整性"
echo `md5sum $install_package` | awk '{print $1}'
echo "If the md5sum is the same with the one  obtained from https://downloads.mysql.com/archives/community/ ?"
read -p "(Please input yes or no):" checkmysql
case "$checkmysql" in 
yes|y|Y|YES|yeS|yES|Yes|YeS|yEs|YEs)
checkmysql='y'
echo "安装包完整,可以开始安装" 
;;
*)
echo "安装包不完整,请重新获取安装包"
checkmysql='n'
exit
esac

## 2. preparations for mysql installation
echo ">>Step2: mysql安装准备中..."
package_tar_name=${install_package##*/}
package_name=${package_tar_name%%.tar*}
## decompress the install package
tar zxvf $package_tar_name -C ${dir_package}/
cd ${dir_package}/
mv ${package_name} mysql
## create user mysql
useradd mysql
## create some directories needed by this installation
cd ${dir_package}/mysql/
touch my.cnf
mkdir -p data
mkdir -p log
mkdir -p mylog
mkdir -p pid
mkdir -p socket
mkdir -p tmp
chown -R mysql:mysql ${dir_package}/mysql

## assign the port for mysql installation 
read -p "Tell me a viable port you'd like to install mysql (the default port is 3306):" port
if [ ! $port ];then
  mport=3306
elif [ !`$port -eq 3306` ];then
  mport=$port
fi
echo "The port="$mport

## define the my.cnf 
cat >>${dir_package}/mysql/my.cnf<<EOF
[client]
port            = $mport
socket          = ${dir_package}/mysql/socket/mysqld-T-prod-$mport.sock
default-character-set=utf8
[mysqld]
user            = mysql
port            = $mport
socket          = ${dir_package}/mysql/socket/mysqld-T-prod-$mport.sock
datadir         = ${dir_package}/mysql/data
basedir         = ${dir_package}/mysql
server-id       = 1
log-bin         = ${dir_package}/mysql/mylog/mysql-bin-T-prod-$mport
sync-binlog=1
tmpdir = ${dir_package}/mysql/tmp
[mysqld_safe]
pid-file        = ${dir_package}/mysql/pid/mysql-T-prod-$mport.pid
log-error       = ${dir_package}/mysql/log/mysql-T-prod-$mport.err
EOF

## Update ${dir_package}/mysql/support-files/mysql.server for mysql start | stop
cd ${dir_package}/mysql/support-files
sed -i "/^datadir=/{s/$/\\${dir_package}\\/mysql\\/data/}" mysql.server    ##datadir=${dir_package}/mysql/data
sed -i "/^basedir=/{s/$/\\${dir_package}\\/mysql/}" mysql.server           ##basedir=${dir_package}/mysql
sed -i "/^mysqld_pid_file_path=/{s/$/\\${dir_package}\\/mysql\\/pid\\/mysql-T-prod-$mport.pid/}" mysql.server
#default_conf="conf=/etc/my.cnf"
#conf="conf=/opt/mysql57/my.cnf"
#sed -i "s/${default_conf}/${conf}/g" mysql.server
sed -i "s/\\/etc\\/my.cnf/\\${dir_package}\\/mysql\\/my.cnf/g" mysql.server  ##conf=${dir_package}/mysql/my.cnf


## 3. initial and start mysql installation
###function installMysql(){
   echo ">>Step3: 开始安装$package_version"
   echo "We are about to install $package_version, please wait..."
   echo ">>Step3-1: 数据库初始化"
   ${dir_package}/mysql/bin/mysqld --defaults-file=${dir_package}/mysql/my.cnf --initialize --user=mysql --basedir=${dir_package}/mysql --datadir=${dir_package}/mysql/data
   echo "=======Very important!! Please remember the password of root if the initial is successful=========="
  
   echo ">>Step3-2: 启动数据库"
   ## 使用mysql用户启动mysql服务(如果mysql没有启动,请手动启动哈)
   su - mysql -s /bin/bash -c "${dir_package}/mysql/support-files/mysql.server start"

   ## 检查mysql启动的进程
   if [ `ps -ef | grep mysql | grep -v grep | wc -l` -eq 0 ]
   then
      echo "Mysql started failed"
   else
      echo "Mysql started successfully"
   fi
###}
##installMysql 2&>1 | tee ${dir_package}/mysql/installMysql.log

## 4. what you need to do after mysql installation
## ① 设置mysql环境变量
#echo `export MYSQL_HOME=${dir_package}/mysql` >> /home/mysql/.bashrc
#echo `export PATH=$PATH:$MYSQL_HOME/bin`>> /home/mysql/.bashrc
#source  /home/mysql/.bashrc

## ② 使用临时root密码登录mysql并修改root密码
#su - mysql
#mysql -uroot -p

#mysql> alter user user() identified by '123456';

定制my.cnf

[root@centos8-min8 mysql]# cat my.cnf

[client]

port            = 3306

socket          = /root/mysql/socket/mysqld-T-prod-3306.sock

default-character-set=utf8

[mysqld]

user            = mysql

port            = 3306

socket          = /root/mysql/socket/mysqld-T-prod-3306.sock

datadir         = /root/mysql/data

basedir         = /root/mysql

tmpdir = /root/mysql/tmp

##server-id       = 1618

##log-bin         = /root/mysql/mylog/mysql-bin-T-prod-3306

##sync-binlog=1

##relay_log       = /root/mysql/mylog/relay-log-T-prod-3306

###log_slave_updates=1

#GTID

gtid_mode=on

enforce_gtid_consistency=on

server-id=1618   #每一台服务器的server-id应该不同

#binlog

log-bin=/root/mysql/mylog/mysql-bin-T-prod-3306

sync-binlog=1

log_slave_updates=1

binlog_format=row

#relay log

skip_slave_start=1

[mysqld_safe]

pid-file        = /root/mysql/pid/mysql-T-prod-3306.pid

log-error       = /root/mysql/log/mysql-T-prod-3306.err

[root@centos8-min8 ~]# mysql -uroot -p

mysql: error while loading shared libraries: libncurses.so.5: cannot open shared object file: No such file or directory

[root@centos8-min8 ~]# yum -y install libncurses*

[root@centos8-min10 ~]# mysql -uroot -p

Enter password:

mysql> alter user user() identified by '123456';

 

3.配置三台服务器基本信息

① 将Hostname与IP进行关联

[root@centos7-min-ha1 ~]# cat /etc/hosts

192.168.16.21 centos7-min-ha1

192.168.16.22 centos7-min-ha2

192.168.16.23 centos7-min-ha3

[root@centos7-min-ha1 ~]# scp /etc/hosts root@192.168.16.22:/etc/hosts

[root@centos7-min-ha1 ~]# scp /etc/hosts root@192.168.16.23:/etc/hosts

② 配置SSH免密登录

[root@centos8-min8 ~]# ssh -V

OpenSSH_8.0p1, OpenSSL 1.1.1c FIPS  28 May 2019   —— CentOS8.2 ssh默认版本

[root@centos7-min-ha1 ~]# ssh -V

OpenSSH_7.4p1, OpenSSL 1.0.2k-fips  26 Jan 2017   —— CentOS7.8 ssh默认版本

/root/.ssh

[root@centos8-min8 ~]# ssh-keygen  ——生成公私钥对

[root@centos8-min8 .ssh]# ll

total 12

-rw-------. 1 root root 2602 Feb  2 17:35 id_rsa

-rw-r--r--. 1 root root  571 Feb  2 17:35 id_rsa.pub

-rw-r--r--. 1 root root  350 Feb  2 13:52 known_hosts

[root@centos8-min8 .ssh]# ssh-copy-id -i /root/.ssh/id_rsa.pub 192.168.16.19 ——把公钥拷贝到其它机器

[root@centos8-min8 .ssh]# ssh-copy-id -i /root/.ssh/id_rsa.pub 192.168.16.20

拷贝完毕之后可在对应机器上查看到公钥信息

[root@centos8-min9 .ssh]# cat /root/.ssh/authorized_keys

[root@centos8-min8 .ssh]# ssh 192.168.16.19 ——min8可免密登录到保存了其公钥的机器

Activate the web console with: systemctl enable --now cockpit.socket

Last login: Tue Feb  2 13:04:52 2021 from 192.168.16.1

[root@centos8-min9 ~]#

同理配置min9和min10两台机器的ssh免密登录即可

4.选择主从模式

> 经典主从复制模式

使用binlog+pos开启复制,在从库指定主库的binlog_file log_pos

MYSQL主备复制可参考 :http://t.csdn.cn/QOKci

> GTID模式

开启GTID,无需找到binlog和pos点,直接change master to master_auto_postion=1即可,它会自动寻找同步

GTID的概述:

1、全局事物标识:global transaction identifieds

2GTID事物是全局唯一性的,且一个事务对应一个GTID

3、一个GTID在一个服务器上只执行一次,避免重复执行导致数据混乱或者主从不一致。

4GTID用来代替classic的复制方法,不在使用binlog+pos开启复制。而是使用master_auto_postion=1的方式自动匹配GTID断点进行复制。

5MySQL-5.6.5开始支持的,MySQL-5.6.10后开始完善。

6、在传统的slave端,binlog是不用开启的,但是在GTID中,slave端的binlog是必须开启的,目的是记录执行过的GTID(强制)。

GTID的组成部分:

前面是server_uuid:后面是一个序列号

例如:server_uuidsequence number

7800a22c-95ae-11e4-983d-080027de205a:10

UUID:每个mysql实例的唯一ID,由于会传递到slave,所以也可以理解为源ID

Sequence number:在每台MySQL服务器上都是从1开始自增长的序列,一个数值对应一个事务。

GTID比传统复制的优势:

1、更简单的实现failover,不用以前那样在需要找log_filelog_Pos

2、更简单的搭建主从复制。

3、比传统复制更加安全。

4GTID是连续没有空洞的,因此主从库出现数据冲突时,可以用添加空事物的方式进行跳过。

GTID的工作原理:

1master更新数据时,会在事务前产生GTID,一同记录到binlog日志中。

2slave端的i/o 线程将变更的binlog,写入到本地的relay log中。

3sql线程从relay log中获取GTID,然后对比slave端的binlog是否有记录。

4、如果有记录,说明该GTID的事务已经执行,slave会忽略。

5、如果没有记录,slave就会从relay log中执行该GTID的事务,并记录到binlog

6、在解析过程中会判断是否有主键,如果没有就用二级索引,如果没有就用全部扫描。

使用GTID搭建mysql的主从复制的主要参数:

[mysqld]

#GTID:

gtid_mode=on

enforce_gtid_consistency=on

server_id=2003306    #每个实例的server_id都要不一样

 

#binlog

log-bin=mysqlbin

log-slave-updates=1   #允许下端接入slave

binlog_format=row      #强烈建议,其他格式可能造成数据不一致

 

#relay log

skip_slave_start=1

注意:建议使用mysql-5.6.5以上的最新版本。

启动GTID的两种方法:

方法一、

1、如果是在已经跑的服务器,你需要重启一下mysql server

2、启动之前,一定要先关闭master的写入,保证所有slave端都已经和master端数据保持同步。

3、所有slave需要加上skip_slave_start=1的配置参数,避免启动后还是使用老的复制协议。

方法二、

1、如果是新搭建的服务器,直接启动就行了。

master-slave搭建的注意事项

(一)、使用GTID的方式,把salve端挂载master端:

1、启动以后最好不要立即执行事务,而是先change master上。

2、然后在执行事务,当然知不是必须的。

3、使用下面的sql切换slave到新的master

stop slave;

change master to

master_host = 192.168.100.200,

master_port = 3306,

master_user = abobo,

master_password=123,

master_auto_position = 1;

()、如果给已经运行的GTIDmaster端添加一个新的slave

 有两种方法:

方法一、适用于master也是新建不久的情况。

1、如果你的master所有的binlog还在。可以选择类似于上面的方法,安装slave,直接change master tomaster端。

2、原理是直接获取master所有的GTID并执行。

3、优点:简单方便。

4、缺点:如果binlog太多,数据完全同步需要时间较长,并且master一开始就启用了GTUD

方法二、适用于拥有较大数据的情况。(推荐)

1、通过master或者其他slave的备份搭建新的slave。(看第三部分)

2、原理:获取master的数据和这些数据对应的GTID范围,然后通过slave设置@@global.gtid_purged跳过备份包含的gtid

3、优点:是可以避免第一种方法的不足。

4、缺点:相对来说有点复杂。

5.搭建主从环境

① 环境说明

本次实验搭建一主两从环境,使用的版本是5.7.28,基于GTID+row+增强半同步模式

GTID —— Global Transaction Identifier

复制格式 —— 推荐使用row格式,statement和mixed格式坑太多。

增强半同步 —— rpl_semi_sync_master_wait_point = AFTER_SYNC

#5.7中默认已经是after_sync

② 在三台MySQL服务器上创建主从复制账号和管理账号

#创建主从复制账号

[mysql@centos8-min8 support-files]$ mysql -uroot -p

Enter password: 123456

mysql> create user 'gtid'@'192.168.16.%' identified by 'gtid123';

mysql> grant replication slave on *.* to 'gtid'@'192.168.16.%';

mysql> flush privileges;

#创建管理账号

mysql> create user 'manage'@'192.168.16.%' identified by 'manage123';

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

mysql> flush privileges;

mysql> select Host,User from mysql.user;

③ 在主库上复制数据到所有从库,完成在某个时刻GTID的同步

[mysql@centos8-min8 mysql]$ mysqldump --single-transaction -uroot -p -A > all.sql

Enter password: 123456

[mysql@centos7-min-ha1 mysql]$ mysqldump --all-databases --triggers --routines --events -uroot -p -A > all.sql

Enter password:

[mysql@centos7-min-ha1 mysql]$

[mysql@centos7-min-ha1 mysql]$ ll

total 1132

-rw-rw-r--.  1 mysql mysql 848521 Feb 23 14:12 all.sql

[root@centos8-min8 mysql]# scp all.sql 192.168.16.19:/root/mysql/

[root@centos8-min8 mysql]# scp all.sql 192.168.16.20:/root/mysql/

④ 从各从库恢复备份并配置主从复制,开启主从同步

[mysql@centos8-min9 mysql]$ mysql -uroot -p < all.sql

[mysql@centos8-min10 mysql]$ mysql -uroot -p < all.sql

> 问题追踪

主要原因是之前的数据库里面配置了主从,再导出的时候一起导出来了,所以导入时会出现这个问题。

解决办法:在导入的服务器重置一下主数据库服务器,再重新导入sql文件即可

 配置文件my.cnf修改(主从服务器配置除server-id之外其余信息一致):

注意:每台MySQL服务器的server-id必须是不一样的!

[mysql@centos7-min-ha1 root]$ vi mysql/my.cnf

[client]

port            = 3306

socket          = /root/mysql/socket/mysqld-T-prod-3306.sock

default-character-set=utf8

[mysqld]

user            = mysql

port            = 3306

socket          = /root/mysql/socket/mysqld-T-prod-3306.sock

datadir         = /root/mysql/data

basedir         = /root/mysql

tmpdir = /root/mysql/tmp

##server-id       = 1620

##log-bin         = /root/mysql/mylog/mysql-bin-T-prod-3306

##sync-binlog=1

##relay_log       = /root/mysql/mylog/relay-log-T-prod-3306

###log_slave_updates=1

#GTID

gtid_mode=on

enforce_gtid_consistency=on

server-id=1621

#binlog

log-bin=/root/mysql/mylog/mysql-bin-T-prod-3306

sync-binlog=1

log_slave_updates=1

binlog_format=row

#relay log

skip_slave_start=1

[mysqld_safe]

pid-file        = /root/mysql/pid/mysql-T-prod-3306.pid

log-error       = /root/mysql/log/mysql-T-prod-3306.err

[root@centos7-min-ha2 ~]# vi mysql/my.cnf

#GTID

gtid_mode=on

enforce_gtid_consistency=on

server-id=1622

[mysql@centos7-min-ha3 mha]$ vi /root/mysql/my.cnf

#GTID

gtid_mode=on

enforce_gtid_consistency=on

server-id=1623

重启主从mysql服务并查看gtid模式启用状态

[mysql@centos8-min8 mysql]$ support-files/mysql.server restart

主库master状态:

从库192.168.16.22同步主库master:

mysql> change master to

    -> master_host='192.168.16.21',

    -> master_port=3306,

    -> master_user='gtid',

    -> master_password='gtid123',

-> master_auto_position=1;

 

从库192.168.16.20同步主库master:

  • 问题追踪

1. gtid_mode未开启

 

 

这个参数gtid_mode是一个单项的修改过程,也就是说从offon,需要经过中间的OFF <-> OFF_PERMISSIVE <-> ON_PERMISSIVE <-> ON

过程,而相邻的两个状态之间可以相互转换。否则会出错。

[mysqld]

gtid_mode=on

enforce_gtid_consistency=on

   2. slave IO进程通信连接不上

     开放mysql端口或者关闭防火墙即可

[root@centos8-min9 ~]# systemctl stop firewalld

[root@centos8-min9 ~]# systemctl disable firewalld

[root@centos8-min9 ~]# systemctl status firewalld

 

服务器挂掉之后MySQL主从同步失败,需要重启slave

 

6.安装MHA-Node节点

在所有节点上安装数据节点

安装MySQL依赖的perl环境

①安装epel

yum install -y epel-release

②安装perl

yum install perl-DBD-MySQL
yum install perl-Config-Tiny
yum install perl-Log-Dispatch
yum install perl-Parallel-ForkManager

yum install perl-Params-Validate

③安装mha-node

tar -zxf mha4mysql-node-0.58.tar.gz

cd mha4mysql-node-0.58/

yum install perl-CPAN* -y

perl Makefile.PL

make && make install

  • 问题追踪

执行yum命令失败,服务器不能访问外网

Cannot find a valid baseurl for repo: base/7/x86_64

添加DNS到网卡配置并重启网络

[root@centos8-min8 ~]# yum install perl-DBD-MySQL -y

解压mha4mysql-node-0.58.tar.gz 并安装 per-cpan

[root@centos8-min8 ~]# tar -zxf mha4mysql-node-0.58.tar.gz

[root@centos8-min8 ~]# cd mha4mysql-node-0.58/

[root@centos8-min8 mha4mysql-node-0.58]# yum install perl-CPAN* -y

perl Makefile.PL

make && make install

Can't locate inc/Module/Install.pm in @INC (you may need to install the inc::Module::Install module)

查看是否安装cpan软件包,已安装后可通过cpan进行perl模块的安装

#yum install perl-CPAN*

[root@centos8-min8 mha4mysql-node-0.58]# cpan inc::Module::Install

> 问题追踪

在centos8.2中执行perl Makefile.PL失败,但在centos7.8中执行成功

7.安装MHA-Manager管理节点

仅在centos7-min-ha3 192.168.16.23上安装mha-manager管理节点

安装环境需要的介质包 —— (在安装MHA-Node的时候已安装了)

①安装mha-manager

[root@centos7-min-ha3 ~]# tar -zxf mha4mysql-manager-0.58.tar.gz

[root@centos7-min-ha3 ~]# chown -R root.root mha4mysql-manager-0.58

[root@centos7-min-ha3 ~]# cd mha4mysql-manager-0.58

[root@centos7-min-ha3 mha4mysql-manager-0.58]# perl Makefile.PL

[root@centos7-min-ha3 mha4mysql-manager-0.58]# make && make install

②配置MHA

mkdir /etc/mha

mkdir -p /usr/local/mha

cd /etc/mha/

[root@centos7-min-ha3 scripts]# cat /etc/mha/mha.conf

[root@centos7-min-ha3 scripts]#

cat /usr/local/mha/scripts/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.16.100/24';  # Virtual IP 这里需要根据自己的环境修改

my $key = "1"; 

##my $ssh_start_vip = "/sbin/ifcfg ens33:$key $vip";    #注意网卡

##my $ssh_stop_vip = "/sbin/ifcfg ens33:$key down";

my $ssh_start_vip = "sudo ip addr add $vip dev ens33:$key";

my $ssh_stop_vip = "sudo ip addr delete $vip dev ens33:$key";

my $exit_code = 0; 

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

            print "Disabling the VIP - $vip on old master: $orig_master_host\n"; 

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

            print "Enabling the VIP - $vip on new master: $new_master_host \n"; 

            print "***************************************************************\n\n\n\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\@$orig_master_host \" $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=po 

rt –new_master_host=host –new_master_ip=ip –new_master_port=port\n"; 

}

[root@centos7-min-ha3 scripts]#

cat /usr/local/mha/scripts/master_ip_online_change

#注意VIP

#/bin/bash 

source /root/.bash_profile 

vip=`echo '192.168.16.100/24'`  # Virtual IP 

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 /sbin/ifcfg  ens33:$key  down"`

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

stop_vip=`echo "ssh root@$orig_master_host sudo ip addr delete 192.168.16.100/24 dev ens33:1"`

start_vip=`echo "ssh root@$new_master_host sudo ip addr add 192.168.16.100/24 dev ens33:1"`

if [ $command = 'stop' ] 

   then 

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

   echo -e "Disabling the 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\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\n" 

fi

检测所有主机的连通性:

[root@centos7-min-ha3 scripts]#

/usr/local/bin/masterha_check_ssh --conf=/etc/mha/mha.conf

解决方法:

SSH互信问题,之前是使用ssh-copy-id命令,所以在authorized_keys中只保存了除本机外的另外两台机器的公钥,需要将三台机器上的本机ssh公钥加入authorized_keys文件

重试成功

检测复制状态:

[root@centos7-min-ha3 mha]#

/usr/local/bin/masterha_check_repl --conf=/etc/mha/mha.conf

问题解决:启动三台服务器上的mysql服务

[root@centos7-min-ha3 mha]# /root/mysql/support-files/mysql.server start

问题解决:需要重启两台mysql从服务的主从同步复制功能

[root@centos7-min-ha3 mha]# su mysql

[mysql@centos7-min-ha3 mha]$ mysql -uroot -p

Enter password: 123456

mysql> start slave;

8.在主库上添加VIP

[root@centos7-min-ha1 ~]# ip addr add 192.168.16.100/24 dev ens33

删除VIP

[root@centos7-min-ha1 ~]# ip addr del 192.168.16.100/24 dev ens33

9.在管理节点启动MHA服务

启动MHA:

nohup masterha_manager --conf=/etc/mha/mha.conf > /tmp/mha_manager.log < /dev/null 2>&1 &

检测MHA是否启动:

masterha_check_status --conf=/etc/mha/mha.conf

注意:

三、模拟主库故障,故障切换

1.MHA自动切换主库

MHA自动切换卡在通过ssh漂移VIP阶段

主要原因是因为master_ip_failover与master_ip_online_change两个文件配置有问题

[root@centos7-min-ha3 scripts]# find / -name mha.failover.complete

/usr/local/mha/mha.failover.complete

[root@centos7-min-ha3 scripts]# cd /usr/local/mha/

[root@centos7-min-ha3 mha]# rm -rf mha.failover.complete

mha.failover.complete 文件:该文件生成后,将不在允许主库故障后自动切换

删除manager机器上的mha.failover.complete文件后,master机器上就能查看到VIP信息

mha-manager正常运行,MySQL主从复制正常,模拟主库故障查看VIP从主库21漂移到从库22

将master MySQL服务停止

[root@centos7-min-ha1 ~]# mysql/support-files/mysql.server stop

Shutting down MySQL........... SUCCESS!

centos7-min-ha1

 centos7-min-ha2

 VIP漂移之后,centos7-min-ha2从库变成主库,查看centos7-min-ha2 的主从状态

 查看centos7-min-ha3 从库的主从状态

> 问题追踪 : 把从库的 Master_Host改成VIP试试,测试结果为不能解决该问题。这个问题产生的原因是min-ha3与min-ha2的server-id配置成了一样的。

注意:每台MySQL服务器的server-id必须是不一样的

2.手动切换主库

前提:一主二从状态正常,主库VIP正常,MHA manager启动正常

停止主库服务,VIP切换到从库min-ha2

[root@centos7-min-ha1 ~]# mysql/support-files/mysql.server stop

Shutting down MySQL........... SUCCESS!

 

mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '123456';

Query OK, 0 rows affected, 1 warning (0.01 sec)

客户端通过VIP访问MySQL服务

数据库主从状态检查

min-ha2 (mater): 自动没有slave

 min-ha3: 自动同步切换master到192.168.16.22

 min-ha1: 没有slave状态,没有同步新master

后续恢复

① 把min-ha1从库与min-ha2主库进行复制

min-ha1:

② 重启min-ha1 MySQL服务后检查Mha manager服务器并删除mha.failover.complete 文件

该文件生成后,将不在允许主库故障后自动切换

再重启mha-manager服务

[root@centos7-min-ha3 mha]#

[root@centos7-min-ha3 mha]# nohup masterha_manager --conf=/etc/mha/mha.conf > /tmp/mha_manager.log < /dev/null 2>&1 &

[root@centos7-min-ha3 mha]# masterha_check_status --conf=/etc/mha/mha.confmha (pid:2641) is running(0:PING_OK), master:192.168.16.22

 

mha.failover.complete存在,min-ha2 (master)故障切换不成功,VIP仍然在min-ha2

再重启min-ha2 MySQL服务,查看主从状态都正常

[root@centos7-min-ha2 ~]# mysql/support-files/mysql.server start

Starting MySQL. SUCCESS!

再测试将/usr/local/mha/mha.failover.complete删除,重启mha服务,再停止MySQL master

[root@centos7-min-ha3 mha]# rm -rf mha.failover.complete

[root@centos7-min-ha3 mha]# nohup masterha_manager --conf=/etc/mha/mha.conf > /tmp/mha_manager.log < /dev/null 2>&1 &

[1] 3127

[root@centos7-min-ha3 mha]# masterha_check_status --conf=/etc/mha/mha.confmha (pid:3127) is running(0:PING_OK), master:192.168.16.22

[root@centos7-min-ha2 ~]# mysql/support-files/mysql.server status

 SUCCESS! MySQL running (2720)

[root@centos7-min-ha2 ~]# mysql/support-files/mysql.server stop

Shutting down MySQL............ SUCCESS!

VIP成功再次切换回min-ha1

MySQL高可用通过,测试完毕。

 

 Min-ha1:

Min-ha2:

Min-ha3:

再将min-ha2以MySQL从机的形式同步min-ha1 MySQL主机

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值