MHA高可用
前言一:MHA架构1.1:MHA概述1.2:MHA的组成1.3:MHA Manager与MHA Node的作用1.31:MHA Manager1.32:MHA Node
1.4:MHA特点1.5:MHA工作原理
二:案列环境2.1:搭建Mysal主从复制环境2.21:修改主机名便于分区各个服务器2.22:安装编译依赖的环境2.23:安装gmak2.24:安装Mysql数据库2.25:修改Master的主配置文件2.26:三台分别启动mysql服务2.27:配置Mysql一主两从2.28:验证主从复制功能
2.2:安装MHA软件2.3:配置接点间SSH免交互登录2.31:在manager上配置到所有数据库节点的无密码认证2.32:在master主服务器配置到数据库slave和tom03的无密码认证2.33:在slave从服务器配置到数据库节点master和tom03的无密码认证2.34:在tom03上配置数据库节点master和slave的无密码认证
2.4:配置MHA2.41:在manager节点上复制相关脚本到/usr/local/bin目录2.42:创建MHA目录并拷贝配置文件2.43:测试ssh无线密码认证:2.44:健康状态检查
2.5:启动HMA2.6:验证
前言
MHA是由日本人youshimaton(原就职于DeNA,现就职于FaceBook)开发的比较成熟的MySQL高可用方案。MHA能够在30秒内实现故障切换,并能在故障切换中,最大可能的保证数据一致性。目前淘宝也正在开发相似产品TMHA,目前已支持一主一从。
一:MHA架构
** MHA由MHA Manager和MHA Node组成。如下图:**
1.1:MHA概述
—套优秀的MySQL高可用环境下故障切换和主从复制的软件MySQL故障过程中,MHA能做到O-30秒内自动完成故障切换
1.2:MHA的组成
MHA Manager(管理节点)MHA Node(数据节点)
1.3:MHA Manager与MHA Node的作用
1.31:MHA Manager
运行一些工具,比如masterha_manager工具实现自动监控MySQL Master和实现master故障切换,其它工具实现手动实现master故障切换、在线mater转移、连接检查等等。一个Manager可以管理多个master-slave集群。
1.32:MHA Node
部署在所有运行MySQL的服务器上,无论是master还是slave。主要作用有三个。
Ⅰ、保存二进制日志如果能够访问故障master,会拷贝master的二进制日志
II、应用差异中继日志从拥有最新数据的slave上生成差异中继日志,然后应用差异日志。
III、清除中继日志在不停止SQL线程的情况下删除中继日志
1.4:MHA特点
自动故障切换过程中,MHA视图从宕机的主服务器上保存二进制日志,最大程度的保证数据不丢失
使用半同步复制,可以大大降低数据丢失的风险
目前MHA支持一主多从架构,最少三台服务,即一两从
1.5:MHA工作原理
当master出现故障时,通过对比slave之间I/O线程读取masterbinlog的位置,选取最接近的slave做为latestslave。其它slave通过与latest slave对比生成差异中继日志。在latest slave上应用从master保存的binlog,同时将latest slave提升为master。最后在其它slave上应用相应的差异中继日志并开始从新的master开始复制。
在MHA实现Master故障切换过程中,MHA Node会试图访问故障的master(通过SSH),如果可以访问(不是硬件故障,比如InnoDB数据文件损坏等),会保存二进制文件,以最大程度保证数据不丢失。MHA和半同步复制一起使用会大大降低数据丢失的危险。
二:案列环境
案列拓扑图如下
实验思路:
1、 安装MySQL数据库2、 配置MySQl一主两从3、 安装MHA软件4、 配置无密码认证5、 配置MySQL MHA 高可用6、 模拟 master 故障切换
实验过程
因为操作系统是centos7,所以要下载MHA 0.57版本 系统:centos 7.6 在三台MySQL 节点上分别安装数据库,MySQL版本请使用5.6.36,cmake版本请使用2.8.6。下面只在Mysql1上面做演示,安装过程如下。
主服务器(master) IP:20.0.0.41 从服务器(slave) IP:20.0.0.42 主/从服务器 (tom03) IP:20.0.0.43 MHA-manager IP: 20.0.0.44
软件包直接下载即可
链接:https://pan.baidu.com/s/1loTBbGw88a9yv5MOi98ZnQ 提取码:owxk
2.1:搭建Mysal主从复制环境
2.21:修改主机名便于分区各个服务器
关闭所有防火墙跟安装防护功能
[root
@localhost ~]
[root
@localhost ~]
[root
@mha ~]
[root
@mha ~]
[root
@localhost ~]
[root
@localhost ~]
[root
@master ~]
[root
@master ~]
[root
@localhost ~]
[root
@localhost ~]
[root
@slave ~]
[root
@slave ~]
[root
@tom03 ~]
[root
@tom03 ~]
2.22:安装编译依赖的环境
三台服务器都安装
[root
@master~]
2.23:安装gmak
[root
@master ~]
anaconda
-ks
.cfg mha4mysql
-manager
-0.57.tar
.gz ruby
-2.4.1.tar
.gz 图片 桌面
cmake
-2.8.6 mha4mysql
-node
-0.57.tar
.gz 公共 文档
cmake
-2.8.6.tar
.gz mysql
-5.6.36 模板 下载
initial
-setup
-ks
.cfg mysql
-5.6.36.tar
.gz 视频 音乐
[root
@master ~]
[root
@master ~]
[root
@master cmake
-2.8.6]
[root
@master cmake
-2.8.6]
2.24:安装Mysql数据库
[root
@master ~]
[root
@master ~]
[root
@master mysql
-5.6.36]
-DCMAKE_INSTALL_PREFIX
=/usr
/local/mysql \
-DDEFAULT_CHARSET
=utf8 \
-DDEFAULT_COLLATION
=utf8_general_ci \
-DWITH_EXTRA_CHARSETS
=all \
-DSYSCONFDIR
=/etc
[root
@master mysql
-5.6.36]
[root
@master mysql
-5.6.36]
[root
@master mysql
-5.6.36]
[root
@master mysql
-5.6.36]
[root
@localhost mysql
-5.6.36]
[root
@master mysql
-5.6.36]
[root
@master mysql
-5.6.36]
[root
@master mysql
-5.6.36]
[root
@master mysql
-5.6.36]
[root
@master mysql
-5.6.36]
[root
@master mysql
-5.6.36]
[root
@master mysql
-5.6.36]
/usr
/local/mysql
/scripts
/mysql_install_db \
2.25:修改Master的主配置文件
三台服务器的server-id不能一样
[root
@master mysql
-5.6.36]
[mysqld
]段落添加
server
-id
=1
log_bin
=master
-bin
log
-slave
-updates
=true
[root
@slave ~]
[mysqld
]段落添加
server
-id
= 2
log_bin
= master
-bin
relay
-log
= relay
-log
-bin
relay
-log
-index = slave
-relay
-bin
.index
[root
@tom03 ~]
server
-id
=3
log_bin
=master
-bin
relay
-log
=relay
-log
-bin
relay
-log
-index=slave
-relay
-bin
.index
ln
-s
/usr
/local/mysql
/bin
/mysql
/usr
/sbin
/
ln
-s
/usr
/local/mysql
/bin
/mysqlbinlog
/usr
/sbin
/
2.26:三台分别启动mysql服务
/usr
/local/mysql
/bin
/mysqld_safe
[root
@master mysql
-5.6.36]
tcp6
0 0 :::
3306 :::
* LISTEN
120279/mysqld
2.27:配置Mysql一主两从
1.Mysql主从配置相对简单,一个是从库同步使用,另一个是manager使用。(三台都配)
#登录数据库
mysql
-uroot
-p
Enter password
: 密码直接回车
grant replication slave on
*.* to
'myslave'@
'20.0.0.%' identified by
'123456';
#配置给manager的监管权限
grant all privileges on
*.* to
'mha'@
'20.0.0.%' identified by
'manager';
#刷新数据库
flush privileges
;
下面三条授权按理论是不用添加的,但是做案例实验环境时候通过MHA检查MySQL主从有报错, 报两个从库通过主机名连接不上主库,所以所有数据库加上下面的授权。
grant all privileges on *.* to 'mha'@'master
' identified by 'manager
';
grant all privileges on *.* to 'mha
'@'slave
' identified by 'manager
';
grant all privileges on *.* to 'mha
'@'tom03
' identified by 'manager'
;
flush
privileges;
主服务器master主机查看二进制文件和同步点
mysql
> show master
status;
+
| File | Position
| Binlog_Do_DB
| Binlog_Ignore_DB
| Executed_Gtid_Set
|
+
| master
-bin
.000001 | 1485 | | | |
+
1 row in set (0.00 sec
)
从服务器slave和tom03都执行同步
change master
to master_host
='20.0.0.41',master_user
='myslave',master_password
='123',master_log_file
='master-bin.000001',master_log_pos
=1485;
flush privileg
;
start slave
;
查看IO和SQL线程都是yes代表同步是否正常。
show slave
status\G
;
...
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
必须设置两个从库为只读模式:
set global read_only
=1;
flush
privileges;
2.28:验证主从复制功能
mysql
> create database niu
;
mysql
> use niu
;
mysql
> create table tt
(id
int(3),name
char(10));
mysql
> insert into tt
(id
,name
) values (1,'zhangsan'),(3,'lisi');
mysql
> select * from tt
;
+
| id
| name
|
+
| 1 | zhangsan
|
| 3 | lisi
|
+
2 rows in set (0.00 sec
)
mysql
> show databases;
+
| Database |
+
| information_schema
|
| mysql
|
| niu
|
| performance_schema
|
| sys
|
+
5 rows in set (0.00 sec
)
mysql
> use niu
;
mysql
> select * from tt
;
+
| id
| name
|
+
| 1 | zhangsan
|
| 3 | lisi
|
+
rows in set (0.00 sec
)
2.2:安装MHA软件
所有服务器上都安装MHA依赖的环境,首先安装epel源
yum install epel
-release
yum install
-y perl
-DBD
-MySQL \
perl
-Config
-Tiny \
perl
-Log
-Dispatch \
perl
-Parallel
-ForkManager \
perl
-ExtUtils
-CBuilder \
perl
-ExtUtils
-MakeMaker \
perl
-CPAN
所有服务器都安装安装node组件,此处仅展示master服务器的安装
[root
@master ~]
[root
@master ~]
[root
@master mha4mysql
-node
-0.57]
[root
@master mha4mysql
-node
-0.57]
在MHA-manager安装manager组件(注意一点要先装node组件才能安装manager组件)
[root
@mha ~]
[root
@mha ~]
[root
@mha mha4mysql
-manager
-0.57]
[root
@mha mha4mysql
-manager
-0.57]
[root
@mha mha4mysql
-manager
-0.57]
manger安装后在/usr/local/bin 下面会生成几个工具,主要包括以下几个
masterha_check_ssh检查MHA的SSH配置状况
masterha_check_repl检查MySQL复制状况
masterha_manger启动manager的脚本
masterha_check_status检测当前MHA运行状态
masterha_master_monitor检测master是否宕机
masterha_master_switch控制故障转移(自动或者手动
)
masterha_conf_host添加或删除配置的server信息
masterha_stop关闭manager
node安装后也会在/usr/local/bin下生成几个脚本(这些脚本通常由MHA Manager的脚本触发,无须人为操作)主要如下
save_binary_logs保存和复制master的二进制日志
apply_diff_relay_logs 识别差异的中继日志事件并将其差异的事件应用于其他的slave
filter_mysqlbinlog去除不必要的
ROLLBACK事件
(MHA已不再使用这个工具
)
purge_relay_logs清除中继日志
(不会阻塞
SQL线程
)
具体如下:
2.3:配置接点间SSH免交互登录
2.31:在manager上配置到所有数据库节点的无密码认证
[root
@mha bin
]
The
key's randomart image is:
+---[RSA 2048]----+
|o+=Oo*o . .. ooo|
| oo.O.=. o ... .|
| o+ = +. o E. . |
|.. +++..o o |
|+o. o.+.S o |
|oo.o + o |
|. . . . . |
| . |
| |
+----[SHA256]-----+
#会生成无密码的密钥对
#.ssh就是生成的密钥对
[root@mha ~]# ls -a /root/.ssh
. .. id_rsa id_rsa.pub
#把密钥对推给三个服务器
[root@mha ~]# ssh-copy-id 20.0.0.41 #创建非对称密码对
..省略内容
Are you sure you want to continue connecting (yes/no)? yes #输入yes
...省略.....
root@20.0.0.41's password:
Permission denied
, please try again
.
root
@20.0.0.41's password:
[root
@mha ~]
[root
@mha ~]
2.32:在master主服务器配置到数据库slave和tom03的无密码认证
[root
@master mha4mysql
-node
-0.57]
[root
@master mha4mysql
-node
-0.57]
[root
@master mha4mysql
-node
-0.57]
2.33:在slave从服务器配置到数据库节点master和tom03的无密码认证
[root
@slave mha4mysql
-node
-0.57]
[root
@slave mha4mysql
-node
-0.57]
[root
@slave mha4mysql
-node
-0.57]
2.34:在tom03上配置数据库节点master和slave的无密码认证
[root
@tom03 mha4mysql
-node
-0.57]
[root
@tom03 mha4mysql
-node
-0.57]
[root
@tom03 mha4mysql
-node
-0.57]
2.4:配置MHA
2.41:在manager节点上复制相关脚本到/usr/local/bin目录
[root
@mha ~]
[root
@mha scripts
]
master_ip_failover power_manager
master_ip_online_change send_report
[root
@mha scripts
]
[root
@mha ~]
[root
@mha scripts
]
总用量
32
-rwxr
-xr
-x
. 1 nginx nginx
3648 5月
31 2015 master_ip_failover
-rwxr
-xr
-x
. 1 nginx nginx
9870 5月
31 2015 master_ip_online_change
-rwxr
-xr
-x
. 1 nginx nginx
11867 5月
31 2015 power_manager
-rwxr
-xr
-x
. 1 nginx nginx
1360 5月
31 2015 send_report
[root
@mha scripts
]
修改一下内容(删除原来的内容)
[root
@mha ~]
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.200';
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;
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
;
}
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
() {
`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";
}
2.42:创建MHA目录并拷贝配置文件
[root
@mha scripts
]
[root
@mha scripts
]
[root
@mha scripts
]
[root
@mha scripts
]
[root
@mha log
]
[server
default]
manager_workdir
=/usr
/log
/masterha
/app1
.log
manager_log
=/var
/log
/masterha
/app1
/manager
.log
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
=123
repl_user
=myslave
report_script
=/usr
/local/send_report
secondary_check_script
=/usr
/local/bin
/masterha_secondary_check
-s
20.0.0.42 -s
20.0.0.43
shutdown_script
=""
ssh_user
=root
user=mha
[server1
]
hostname
=20.0.0.41
port
=3306
[server2
]
hostname
=20.0.0.42
port
=3306
candidate_master
=1
check_repl_delay
=0
[server3
]
hostname
=20.0.0.43
port
=3306
配置文件的解析如下
[server
default]
manager_workdir
=/usr
/log
/masterha
/app1
.log
manager_log
=/var
/log
/masterha
/app1
/manager
.log
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
user=mha
ping_interval
=1
remote_workdir
=/tmp
repl_password
=123
repl_user
=myslave
report_script
=/usr
/local/send_report
secondary_check_script
=/usr
/local/bin
/masterha_secondary_check
-s
192.168.50.133 -s
192.168.50.134
shutdown_script
=""
ssh_user
=root
[server2
]
candidate_master
=1
check_repl_delay
=0
2.43:测试ssh无线密码认证:
如果正常会输出successfully,如下所示
[root
@mha ~]
Sat Aug
29 20:
35:
03 2020 - [warning
] Global configuration
file /etc
/masterha_default
.cnf
not found
. Skipping
.
Sat Aug
29 20:
35:
03 2020 - [info
] Reading application
default configuration
from /etc
/masterha
/app1
.cnf
..
Sat Aug
29 20:
35:
03 2020 - [info
] Reading server configuration
from /etc
/masterha
/app1
.cnf
..
Sat Aug
29 20:
35:
03 2020 - [info
] Starting SSH connection tests
..
Sat Aug
29 20:
35:
05 2020 - [debug
]
Sat Aug
29 20:
35:
03 2020 - [debug
] Connecting via SSH
from root
@20.0.0.41(20.0.0.41:
22) to root
@20.0.0.42(20.0.0.42:
22)..
Sat Aug
29 20:
35:
04 2020 - [debug
] ok
.
Sat Aug
29 20:
35:
04 2020 - [debug
] Connecting via SSH
from root
@20.0.0.41(20.0.0.41:
22) to root
@20.0.0.43(20.0.0.43:
22)..
Sat Aug
29 20:
35:
05 2020 - [debug
] ok
.
Sat Aug
29 20:
35:
06 2020 - [debug
]
Sat Aug
29 20:
35:
04 2020 - [debug
] Connecting via SSH
from root
@20.0.0.43(20.0.0.43:
22) to root
@20.0.0.41(20.0.0.41:
22)..
Sat Aug
29 20:
35:
05 2020 - [debug
] ok
.
Sat Aug
29 20:
35:
05 2020 - [debug
] Connecting via SSH
from root
@20.0.0.43(20.0.0.43:
22) to root
@20.0.0.42(20.0.0.42:
22)..
Sat Aug
29 20:
35:
06 2020 - [debug
] ok
.
Sat Aug
29 20:
35:
06 2020 - [debug
]
Sat Aug
29 20:
35:
04 2020 - [debug
] Connecting via SSH
from root
@20.0.0.42(20.0.0.42:
22) to root
@20.0.0.41(20.0.0.41:
22)..
Sat Aug
29 20:
35:
04 2020 - [debug
] ok
.
Sat Aug
29 20:
35:
04 2020 - [debug
] Connecting via SSH
from root
@20.0.0.42(20.0.0.42:
22) to root
@20.0.0.43(20.0.0.43:
22)..
Sat Aug
29 20:
35:
05 2020 - [debug
] ok
.
Sat Aug
29 20:
35:
06 2020 - [info
] All SSH connection tests passed successfully
.
2.44:健康状态检查
masterha_check_repl
-conf
=/etc
/masterha
/app1
.cnf
MySQL
Replication Health
is OK
.
ps:结果不正确是
is not OK!
健康检查没问题后去手动开启虚拟IP【master服务器】
[root@master
~]#
/sbin
/ifconfig ens33
:1 20.0.0.200/24
2.5:启动HMA
nohup masterha_manager
PS:有的时候会提示“没有这个文件或目录”是因为没有建立日志存放目录,所以我们需要去手动在
/var
/log
/目录下创建masterha目录,在其中再创建app1目录
[root
@localhost ~]
查看MHA状态。可以看到当前的是master是master节点
masterha_check_status
--conf
=/etc
/masterha
/app1
.cnf
app1 (pid
:86379) is
running(0:PING_OK), master
:20.0.0.41
查看master的VIP地址是否存在?这个VIP地址不会因为manager节点停止服务而消失
ens33
:1: flags
=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu
1500
inet
20.0.0.200 netmask
255.255.255.0 broadcast
20.0.0.255
ether
00:0c
:29:84:c1
:e3 txqueuelen
1000 (Ethernet
)
2.6:验证
模拟故障进行故障转换恢复1)在生产环境中, 当你的主节点挂了后, 一定要在从节点上做一个备份, 拿着备份文件把主节点手动提升为从节点, 并指明从哪一个日志文件的位置开始复制2)每一次自动完成转换后, 每一次的(replication health )检测不ok始终都是启动不了必须手动修复主节点, 除非你改配置文件3)手动修复主节点提升为从节点后, 再次运行检测命令
[root
@master ~]
tcp6
0 0 :::
3306 :::
* LISTEN
112987/mysqld
tcp6
0 0 20.0.0.41:
3306 20.0.0.43:
52352 ESTABLISHED
112987/mysqld
tcp6
0 0 20.0.0.41:
3306 20.0.0.42:
39738 ESTABLISHED
112987/mysqld
tcp6
0 0 20.0.0.41:
3306 20.0.0.44:
59948 ESTABLISHED
112987/mysqld
[root
@master ~]
再次查看端口服务已经关闭
完赖结束了