目录

一、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介绍

MHA(Master 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 ];thenmport=3306
elif [ !`$port -eq 3306` ];thenmport=$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/dataecho "=======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 ]thenecho "Mysql started failed"elseecho "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。

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

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

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

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

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

② GTID的组成部分:

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

例如:server_uuid:sequence number

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

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

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

③ GTID比传统复制的优势:

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

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

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

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

④ GTID的工作原理:

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

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

3、sql线程从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;

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

有两种方法:

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

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

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是一个单项的修改过程,也就是说从off到on,需要经过中间的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主机

MYSQL高可用环境搭建相关推荐

  1. MHA+keepalive高可用环境搭建

    MHA+keepalive高可用环境搭建 2017年02月17日 14:05:57 阅读数:2582 MHA(Master HighAvailability)目前在MySQL高可用方面是一个相对成熟的 ...

  2. docker mysql 高可用_docker搭建数据库高可用方案PXC

    前言 本方案主要目的是学习, 该方案不太合适于企业项目 是什么? 白话点, 是个提供了必要环境的虚拟机(类似于java的导入部分包一样和c++的头文件差不多), 所以它比普通的VMWare或者Virt ...

  3. MySQL高可用方案-PXC环境部署记录

    之前梳理了Mysql+Keepalived双主热备高可用操作记录,对于mysql高可用方案,经常用到的的主要有下面三种: 一.基于主从复制的高可用方案:双节点主从 + keepalived 一般来说, ...

  4. Heartbeat+DRBD+MySQL高可用方案

    1.方案简介 本方案采用Heartbeat双机热备软件来保证数据库的高稳定性和连续性,数据的一致性由DRBD这个工具来保证.默认情况下只有一台mysql在工作,当主mysql服务器出现问题后,系统将自 ...

  5. MySQL高可用架构

    MySQL学习笔记 一,高可用架构 对于一个企业来讲,设计一个高可用的架构非常重要,包括前端的高可用和后端数据库的高可用.企业业务每暂停一分钟,可能会造成大量的金钱流失,因此只有在整个架构的设计上足够 ...

  6. MySQL——Keepalived+Mysql高可用架构实战

    摘要 在生产环境中mysql的高可用的对于整个项目而言有着至关重要的作用.因此需要将mysql设计成为高可用的架构.本博文将详细介绍的mysql+keepalived构建的mysql互为主从的架构实战 ...

  7. mysql+keepalived搭建高可用环境

    假设已经搭建好了mysql并且存在正常状态的主主复制 1.安装keepalived并且根据业务的vip及主机网卡,ip配置好/etc/keepalived/keepalived.conf,具体操作已在 ...

  8. 阿里高可用mysql搭建方案_阿里云环境迁移记录 - MYSQL高可用搭建

    MYSQL高可用方案主要分为两大类,一类是前置管理,一类是后置管理. 前置管理的思想是利用各种前置管理工具,动态切换或者分发请求到不同的实例并切换master,如keepalived.MHA.pack ...

  9. 搭建MySQL高可用架构MHA

    搭建MySQL高可用架构MHA v1.0 MHA简介 MHA的主要目的是自动化master故障转移和slave自动提升为master,在较短时间(一般为10-30秒)的停机时间,可以避免复制和一致性问 ...

最新文章

  1. mongoose手动生成ObjectId
  2. 我们遇到什么困难都不要怕,微笑着面对它
  3. B1277 [HNOI2002]Tinux系统 树形dp
  4. Spring.Resource与Spring资源获取方式
  5. 求数组非连续子序列的最大和
  6. 故人的一份连连看代码,c语言版本
  7. java reader_Java Reader ready()方法与示例
  8. FusionCharts 中文乱码
  9. 阿里云、腾讯云、UCloud 、华为云云主机对比测试报告
  10. python能做什么程序-Python可以被用来做哪些神奇好玩的事情
  11. 用R和BioConductor进行基因芯片数据分析(三):计算median
  12. python调用java完整教程
  13. 中国城市统计年鉴1985-2021中国城市年鉴面板数据(完美Excel版)
  14. Android7.0 MessageQueue
  15. 文件共享服务器如何提高网速,局域网共享文件传输速度很慢怎么办
  16. 30行python代码实现豆瓣电影排行爬取
  17. 怎样才能成为一名有创造力的领导者?
  18. python怎么检查页面边距_Matplotlib页边距
  19. nu.xom.IllegalNameException: 0x20 is not a legal NCName character
  20. 吊打面试官系列之:UI自动化面试题汇总,对标P7,从此再也不怕面试官了。

热门文章

  1. mysql外键约束案例_详解MySQL中的外键约束问题
  2. 电视android怎么连接手机助手,海信电视微助手怎么帮助手机连接电视机 方法介绍...
  3. jacob 字体设置
  4. “破晓之战”星杯传说赛后复盘分析
  5. 《逆赛博格教堂与集市》——国内首个基于区块链的人与AI协作艺术展即将开幕...
  6. Vue核心⑨(数据监测原理)
  7. LAMP[Discuz论坛]
  8. rest-assured的xmlPath使用方法总结
  9. python使用loaddata_Python data.load_data方法代码示例
  10. “人脸识别“解锁,到底安全不安全?