MHA高可用及故障切换实验
一、MHA简介1.1、MHA(Master High Availability)1.2、MHA工作原理总结为以下几条:
二、实验架构设计2.1、基本环境2.2 一主两从搭建
三、MHA四、验证模拟故障master宕机,看备机是否接替地址是否漂移
一、MHA简介
1.1、MHA(Master High Availability)
目前在MySQL高可用方面是一个相对成熟的解决方案,它由日本DeNA公司youshimaton(现就职于Facebook公司)开发,是一套优秀的作为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服务器上,因此可以保证所有节点的数据一致性。
1.2、MHA工作原理总结为以下几条:
1、从宕机崩溃的master保存二进制日志事件(binlog events); 2、识别含有最新更新的slave; 3、应用差异的中继日志(relay log)到其他slave; 4、应用从master保存的二进制日志事件(binlog events); 5、提升一个slave为新master; 6、使用其他的slave连接新的master进行复制。 官方介绍:https://code.google.com/archive/p/mysql-master-ha/
二、实验架构设计
2.1、基本环境
· 操作系统版本:CentOS 7.6 · MySQL版本:5.6.14 · VIP(虚IP):172.16.1.100 · 主机信息:见表1
角色IP主机名MYSQL版本server_idVIP
Master20.0.0.30MYSQL15.7120.0.0.33Master-Slave20.0.0.31MYSQL25.72Slave20.0.0.32MYSQL35.73Manager20.0.0.34MHA-Manager5.7
实验思路: 1.MHA架构 1)数据库安装 2)一主两从 3)MHA搭建
2.故障模拟 1)主库失效 2)备选主库成为主库 3)从库2将备选主库指向为主库
2.2 一主两从搭建
1. 安装编译依赖的环境
[root@localhost
~]# yum
-y install \
ncurses
-devel \
gcc
-c
++ \
perl
-Module
-Install
2. 安装 gmake 编译软件
[root@localhost
~]# tar zxvf cmake
-2.8.6.tar
.gz
[root@localhost
~]# cd cmake
-2.8.6
[root@localhost cmake
-2.8.6]#
./configure
[root@localhost cmake
-2.8.6]# gmake
&& gmake install
3. 安装 MySQL 数据库
[root@localhost
~]# tar
-zxvf mysql
-5.6.36.tar
.gz
[root@localhost
~]# cd mysql
-5.6.36
cmake
-DCMAKE_INSTALL_PREFIX
=/usr
/local
/mysql \
-DDEFAULT_CHARSET
=utf8 \
-DDEFAULT_COLLATION
=utf8_general_ci \
-DWITH_EXTRA_CHARSETS
=all \
-DSYSCONFDIR
=/etc
[root@localhost mysql
-5.6.36]# make
&& make install
[root@localhost mysql
-5.6.36]# cp support
-files
/my
-default.cnf
/etc
/my
.cnf
[root@localhost mysql
-5.6.36]# cp support
-files
/mysql
.server
/etc
/rc
.d
/init
.d
/mysqld
[root@localhost
~]# chmod
+x
/etc
/rc
.d
/init
.d
/mysqld
[root@localhost
~]# chkconfig
--add mysqld
[root@localhost
~]# echo
"PATH=$PATH:/usr/local/mysql/bin" >> /etc
/profile
[root@localhost
~]# source
/etc
/profile
[root@localhost
~]# groupadd mysql
[root@localhost
~]# useradd
-M
-s
/sbin
/nologin mysql
-g mysql
[root@localhost
~]# chown
-R mysql
.mysql
/usr
/local
/mysql
[root@localhost
~]# mkdir
-p
/data
/mysql
/usr
/local
/mysql
/scripts
/mysql_install_db \
--basedir
=/usr
/local
/mysql \
--datadir
=/usr
/local
/mysql
/data \
--user
=mysql
4.修改主机名,主从分别mysql1、mysql2、mysql3,后面授权是对主机名进行授权所以需要进行修改
[root@localhost
~]# hostnamectl set
-hostname mysql1
[root@localhost
~]# su
5.做名称解析,主从都要做
[root@mysql1
~]# vi
/ect
/hosts
127.0.0.1 localhost localhost
.localdomain localhost4 localhost4
.localdomain4
::1 localhost localhost
.localdomain localhost6 localhost6
.localdomain6
20.0.0.30 mysql1 ####添加一下三行,ip地址根据自己设置进行修改
20.0.0.31 mysql2
20.0.0.32 mysql3
[root@mysql1
~]# ping mysql2 ###设置好ping一下从机主机名能ping通说明没问题
PING mysql2
(20.0.0.31) 56(84) bytes of data
.
64 bytes from mysql2
(20.0.0.31): icmp_seq
=1 ttl
=64 time
=0.490 ms
64 bytes from mysql2
(20.0.0.31): icmp_seq
=2 ttl
=64 time
=0.396 ms
64 bytes from mysql2
(20.0.0.31): icmp_seq
=3 ttl
=64 time
=0.390 ms
64 bytes from mysql2
(20.0.0.31): icmp_seq
=4 ttl
=64 time
=0.366 ms
6. 修改 Master 的主配置文件
/etc
/my
.cnf 文件,三台服务器的
server
-id 不能一样
[root@Mysql1
~]# cat
/etc
/my
.cnf ####修改mysql1
[client
]
port
= 3306
#default-character-set=utf8 ###这里字符集一定要注释掉,不然后面健康检查会报错 细节
socket
= /usr
/local
/mysql
/mysql
.sock
[mysqld
]
server
-id
= 1 ###重点每台都不能一样
log_bin
= master
-bin ###开启二进制日志
log
-slave
-updates
= true ###允许进行同步
配置从服务器:mysql2
在
/etc
/my
.cnf 中修改或者增加下面内容。
[root@Mysql2
~]# vim
/etc
/my
.cnf
[client
]
port
= 3306
#default-character-set=utf8 ###这里字符集一定要注释掉,不然后面健康检查会报错 细节
socket
= /usr
/local
/mysql
/mysql
.sock
[mysqld
]
server
-id
= 2
log_bin
= master
-bin
relay
-log
= relay
-log
-bin ####中继日志要开启
relay
-log
-index
= slave
-relay
-bin
.index ###索引要开启
配置从服务器:mysql3
在
/etc
/my
.cnf 中修改或者增加下面内容。
[root@Mysql2
~]# vim
/etc
/my
.cnf
[client
]
port
= 3306
#default-character-set=utf8 ###这里字符集一定要注释掉,不然后面健康检查会报错 细节
socket
= /usr
/local
/mysql
/mysql
.sock
[mysqld
]
server
-id
= 3
log_bin
= master
-bin
relay
-log
= relay
-log
-bin ####中继日志要开启
relay
-log
-index
= slave
-relay
-bin
.index ###索引要开启
[root@mysql1
~]# systemctl restart mysqld ####配置文件修该完一定要刷新一下
7. Mysql1、Mysql2、Mysql3 分别做两个软链接
[root@Mysql1
~]# ln
-s
/usr
/local
/mysql
/bin
/mysql
/usr
/sbin
/
[root@Mysql1
~]# ln
-s
/usr
/local
/mysql
/bin
/mysqlbinlog
/usr
/sbin
/
8、Mysql1、Mysql2、Mysql3 分别启动 MySQL。
[root@Mysql1
~]# systemctl start mysqld
9.配置 MySQL 一主两从
1. 授权,步骤如下:
在所有数据库节点上授权两个用户,一个是从库同步使用,另外一个是 manager 使用。
mysql
> grant replication slave on
*.* to
'myslave'@
'20.0.0.%' identified by
'123456';
mysql
> grant all privileges on
*.* to
'mha'@
'20.0.0.%' identified by
'manager';
mysql
> flush privileges
;
2. 在 Mysql1 主机上查看二进制文件和同步点
mysql
> show master status
;
+-------------------+----------+--------------+------------------+-------------------+
| File
| Position
| Binlog_Do_DB
| Binlog_Ignore_DB
| Executed_Gtid_Set
|
+-------------------+----------+--------------+------------------+-------------------+
| master
-bin
.000001 | 1523 | | | |
+-------------------+----------+--------------+------------------+-------------------
3. 接下来在 Mysql2 和 Mysql3 分别执行同步。
mysql
> change master to master_host
='20.0.0.30',master_user
='myslave',master_password
='123456',master_log_file
='master-bin.000001',master_log_pos
=1050;
mysql
> start slave
;
mysql
> show slave status\G
;
*************************** 1. row
***************************
Slave_IO_State
: Waiting
for master to send event
Master_Host
: 20.0.0.30
Master_User
: myslave
Master_Port
: 3306
Connect_Retry
: 60
Master_Log_File
: master
-bin
.000004
Read_Master_Log_Pos
: 154
Relay_Log_File
: relay
-log
-bin
.000005
Relay_Log_Pos
: 369
Relay_Master_Log_File
: master
-bin
.000004
Slave_IO_Running
: Yes
Slave_SQL_Running
: Yes
显示双yes说明主从同步已经建立好了
必须设置两个从库为只读模式:
mysql
> set global read_only
=1;
去主master建个库,在从上面看下有没有同步
#### mysql1上创建
mysql
> create database school
;
Query OK
, 1 row affected
(0.00 sec
)
###### mysql2、
3上查询下
mysql
> show databases
;
+--------------------+
| Database
|
+--------------------+
| information_schema
|
| mysql
|
| performance_schema
|
| school
|
| sys
|
+--------------------+
5 rows in set
(0.00 sec
)
#### 验证没问题
三、MHA
################安装 MHA 软件#################
1. 所有服务器上都安装 MHA 依赖的环境,首先安装 epel 源。
[root@MHA
-manager
~]# yum install epel
-release
--nogpgcheck
-y ####安装扩展源
yum install
-y perl
-DBD
-MySQL \
perl
-Config
-Tiny \
perl
-Log
-Dispatch \
perl
-Parallel
-ForkManager \
perl
-ExtUtils
-CBuilder \
perl
-ExtUtils
-MakeMaker \
perl
-CPAN
2. MHA 软件包对于每个操作系统版本不一样,这里 CentOS7
.6 选择
0.57 版本,
在
<注意:所有服务器
>上必须先安装 node 组件,最后在 MHA
-manager 节点上安装 manager 组件,
因为 manager 依赖 node 组件,下面都是在 Mysql1 上操作演示安装 node 组件。
[root@localhost
~]# tar zxvf mha4mysql
-node
-0.57.tar
.gz
[root@localhost
~]# cd mha4mysql
-node
-0.57
[root@localhost mha4mysql
-node
-0.57]# perl Makefile
.PL
[root@localhost mha4mysql
-node
-0.57]# make
&& make install
3. 在 MHA
-manager 上安装 manager 组件
[root@localhost mha4mysql
-node
-0.57]# cd
~
[root@localhost
~]# tar zxvf mha4mysql
-manager
-0.57.tar
.gz
[root@localhost
~]# cd mha4mysql
-manager
-0.57
[root@localhost mha4mysql
-manager
-0.57]# perl Makefile
.PL
[root@localhost mha4mysql
-manager
-0.57]# make
&& make install
[root@localhost mha4mysql
-manager
-0.57]# cd
~
4. 配置无密码认证
在 manager 上配置到所有数据库节点的无密码认证
[root@localhost
~]# ssh
-keygen
-t rsa ###一直按空格,不设置密码
[root@localhost
~]# ssh
-copy
-id
20.0.0.30
/usr
/bin
/ssh
-copy
-id
: INFO
: Source of
key(s
) to be installed
: "/root/.ssh/id_rsa.pub"
The authenticity of host
'20.0.0.30 (20.0.0.30)' can't be established
.
ECDSA key fingerprint is SHA256
:0dN16et6qjB9Jw6XVgJpur9TOu0sPqWUuzBt6tE08ss
.
ECDSA key fingerprint is MD5
:50:ab
:bc
:a1
:ce
:86:4a
:ec
:08:49:63:8b
:ff
:8e
:bd
:5f.
Are you sure you want to
continue connecting
(yes
/no
)? yes ##这里输入yes
Number of
key(s
) added
: 1 ####这里是
1表示设置成功
[root@localhost
~]# ssh
-copy
-id
20.0.0.31
[root@localhost
~]# ssh
-copy
-id
20.0.0.32 ####过程同上
[root@localhost
~]# cp
-ra
/root
/mha4mysql
-manager
-0.57/samples
/scripts
/usr
/local
/bin
[root@localhost
~]# ll
/usr
/local
/bin
/scripts
total
32
-rwxr
-xr
-x
. 1 1001 1001 3648 May
31 2015 master_ip_failover
-rwxr
-xr
-x
. 1 1001 1001 9870 May
31 2015 master_ip_online_change
-rwxr
-xr
-x
. 1 1001 1001 11867 May
31 2015 power_manager
-rwxr
-xr
-x
. 1 1001 1001 1360 May
31 2015 send_report
##########解释#######
master_ip_failover #自动切换时 VIP 管理的脚本
master_ip_online_change #在线切换时 vip 的管理
master_ip_online_change #在线切换时 vip 的管理
master_ip_online_change #在线切换时 vip 的管理
############################################
[root@localhost
~]# cp
/usr
/local
/bin
/scripts
/master_ip_failover
/usr
/local
/bin
[root@localhost
~]# 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
);
#############################添加内容部分#########################################
my $vip
= '20.0.0.33';
my $brdc
= '20.0.0.255';
my $ifdev
= 'ens33';
my $key
= '1';
my $ssh_start_vip
= "/sbin/ifconfig ens33:$key $vip";
my $ssh_stop_vip
= "/sbin/ifconfig ens33:$key down";
my $exit_code
= 0;
#my $ssh_start_vip = "/usr/sbin/ip addr add $vip/24 brd $brdc dev $ifdev label $ifdev:$key;/usr/sbin/arping -q -A -c 1 -I $ifdev $vip;iptables -F;";
#my $ssh_stop_vip = "/usr/sbin/ip addr del $vip/24 dev $ifdev label $ifdev:$key";
##################################################################################
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";
}
###########################################################################
4. 创建 MHA 软件目录并拷贝配置文件。
[root@MHA
-manager
~]# mkdir
/etc
/masterha
[root@MHA
-manager
~]# cp
/root
/mha4mysql
-manager
-0.57/samples
/conf
/app1
.cnf
/etc
/masterha
/
[root@MHA
-manager
~]# vim
/etc
/masterha
/app1
.cnf ####清除原有 直接复制修改
[server
default]
manager_log
=/var
/log
/masterha
/app1
/manager
.log
manager_workdir
=/var
/log
/masterha
/app1
master_binlog_dir
=/usr
/local
/mysql
/data
master_ip_failover_script
=/usr
/local
/bin
/master_ip_failover
master_ip_online_change_script
=/usr
/local
/bin
/master_ip_online_change
password
=manager ####账户
ping_interval
=1
remote_workdir
=/tmp
repl_password
=123456 #####之前设置的密码
repl_user
=myslave ##### 账户
secondary_check_script
=/usr
/local
/bin
/masterha_secondary_check
-s
20.0.0.31-s
20.0.0.32
#####这里的IP是从服务器地址
shutdown_script
=""
ssh_user
=root
user
=mha
[server1
]
hostname
=20.0.0.30 ###该ip地址,这里有几个server就添加几个
port
=3306
[server2
]
candidate_master
=1
check_repl_delay
=0
hostname
=20.0.0.31
port
=3306
[server3
]
hostname
=20.0.0.32
port
=3306
##########################################
验证ssh 无密码认证,如果正常最后会输出 successfully,如下所示
注意:第一次配置需要去master上手动开启虚拟IP
[root@Mysql1
~]#
/sbin
/ifconfig ens33
:1 20.0.0.33/24
再去启动MHA
[root@localhost
~]# nohup masterha_manager
--conf
=/etc
/masterha
/app1
.cnf
--remove_dead_master_conf
--ignore_last_failover
< /dev
/null
> /var
/log
/masterha
/app1
/manager
.log
2>&1 &
[1] 31924
查看 MHA 状态,可以看到当前的 master 是 Mysql1 节点
[root@localhost
~]# masterha_check_status
--conf
=/etc
/masterha
/app1
.cnf
app1
(pid
:31924) is
running(0:PING_OK
), master
:20.0.0.30
#################验证########################
[root@localhost
~]# tailf
/var
/log
/masterha
/app1
/manager
.log ###开启监控
四、验证模拟故障master宕机,看备机是否接替地址是否漂移
在master上关闭mysql看是否转换主 已经切换了,现在看漂移地址
vip已经转移到新的master上了