目录
一、MHA概述
1、MHA简介
(1)MHA(MasterHigh Availability)是一套优秀的MySQL高可用环境下故障切换和主从复制的软件。
(2)MHA 的出现就是解决MySQL 单点故障的问题。
(3)MySQL故障切换过程中,MHA能做到0-30秒内自动完成故障切换操作。
(4)MHA能在故障切换的过程中最大程度上保证数据的一致性,以达到真正意义上的高可用。
2、MHA 的组成
MHA Node(数据节点)
MHA Node 运行在每台 MySQL 服务器上。
MHA Manager(管理节点)
MHA Manager 可以单独部署在一台独立的机器上,管理多个 master-slave 集群;也可以部署在一台 slave 节点上。
MHA Manager 会定时探测集群中的 master 节点。当 master 出现故障时,它可以自动将最新数据的 slave 提升为新的 master, 然后将所有其他的 slave 重新指向新的 master。整个故障转移过程对应用程序完全透明。
MHA 的特点
●自动故障切换过程中,MHA试图从宕机的主服务器上保存二进制日志,最大程度的保证数据不丢失
●使用半同步复制,可以大大降低数据丢失的风险,如果只有一个slave已经收到了最新的二进制日志,MHA可以将最新的二进制日志应用于其他所有的slave服务器上,因此可以保证所有节点的数据一致性
●目前MHA支持一主多从架构,最少三台服务,即一主两从
二、搭建 MySQL MHA
搭建MHA manager 服务器
首先数据库服务器不能联网,需要建立一个时间同步服务器(192.168.10.104)
第一步:初始化
[root@localhost ~]# systemctl disable --now firewalld
[root@localhost ~]# setenforce 0
[root@localhost ~]# vim /etc/selinux/config
第二步:
vim /etc/chrony.conf
systemctl restart chronyd
第三步:设置主机名
hostnamectl set-hostname manager
第四步:安装MHA依赖的环境、安装epel源
vim /etc/yum.conf
----
cachedir=/opt/yumcache
keepcache=1
----
cd /opt
mkdir /opt/yumcache
cd /etc/yum.repos.d
mv repo.bak/* ./
mv local.repo repo.bak
cd /opt/yumcache
yum install -y 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
将依赖包挪入yumcache,并将包复制到各个主服务器
mkdir mha
find ./ -name "*.rpm" -exec mv {} ./mha/ \; #将依赖包挪入该目录
scp -r mha/ 192.168.10.20:/opt #将包复制到主服务器
scp -r mha/ 192.168.10.21:/opt #将包复制到从服务器
scp -r mha/ 192.168.10.22:/opt #将包复制到从服务器
第五步:安装node组件
cd /opt
rz -E
#mha4mysql-node-0.57.tar.gz
tar xf mha4mysql-node-0.57.tar.gz
cd mha4mysql-node-0.57/
perl Makefile.PL && make && make install
第六步:安装manager组件
cd /opt
rz -E
#mha4mysql-manager-0.57.tar.gz
tar zxvf mha4mysql-manager-0.57.tar.gz
cd mha4mysql-manager-0.57
perl Makefile.PL
make && make install
注:manager 组件安装后在/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 下面会生成几个脚本(这些工具通常由 MHAManager 的脚本触发,无需人为操作)主要如下
save_binary_logs 保存和复制 master 的二进制日志
apply_diff_relay_logs 识别差异的中继日志事件并将其差异的事件应用于其他的 slave
filter_mysqlbinlog 去除不必要的 ROLLBACK 事件(MHA 已不再使用这个工具)
purge_relay_logs 清除中继日志(不会阻塞 SQL 线程)
第七步:配置无密码认证
在 manager 节点上配置到所有数据库节点的无密码认证
ssh-keygen -t rsa #一路按回车键
ssh-copy-id 192.168.9.150
ssh-copy-id 192.168.9.210
ssh-copy-id 192.168.9.120
第八步:manager节点配置MHA
cd /opt/mha4mysql-manager-0.57/samples
cp -a scripts/ /usr/local/bin
cd /usr/local/bin
cp scripts/master_ip_failover /usr/local/bin
[root@manager bin]# ls
apply_diff_relay_logs masterha_check_repl masterha_check_status masterha_manager masterha_master_switch masterha_stop purge_relay_logs scripts
filter_mysqlbinlog masterha_check_ssh masterha_conf_host masterha_master_monitor masterha_secondary_check master_ip_failover save_binary_logs
[root@manager bin]# vim master_ip_failover
[root@manager bin]# ls
apply_diff_relay_logs masterha_check_ssh masterha_manager masterha_secondary_check master_ip_failover_2.txt scripts
filter_mysqlbinlog masterha_check_status masterha_master_monitor masterha_stop purge_relay_logs
masterha_check_repl masterha_conf_host masterha_master_switch master_ip_failover save_binary_logs
[root@manager bin]# mv master_ip_failover_2.txt master_ip_failover
mv:是否覆盖"master_ip_failover"? yes
------清空原先master_ip_failover的内容添加以下配置
vim master_ip_failover
------清空原先master_ip_failover的内容添加以下配置
#!/usr/bin/env perl
use strict;
use warnings FATAL => 'all';
use Getopt::Long;
my (
$command, $orig_master_host, $orig_master_ip,$ssh_user,
$orig_master_port, $new_master_host, $new_master_ip,$new_master_port,
$orig_master_ssh_port,$new_master_ssh_port,$new_master_user,$new_master_password
);
# 这里定义的虚拟IP配置要注意,这个ip必须要与你自己的集群在同一个网段,否则无效
my $vip = '192.168.9.100/24';
my $key = '1';
# 这里的网卡名称 “ens33” 需要根据你机器的网卡名称进行修改
# 如果多台机器直接的网卡名称不统一,有两种方式,一个是改脚本,二是把网卡名称修改成统一
# 我这边实际情况是修改成统一的网卡名称
my $ssh_start_vip = "sudo /sbin/ifconfig ens33:$key $vip";
my $ssh_stop_vip = "sudo /sbin/ifconfig ens33:$key down";
my $ssh_Bcast_arp= "sudo /sbin/arping -I ens33 -c 3 -A $vip";
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,
'orig_master_ssh_port=i' => \$orig_master_ssh_port,
'new_master_host=s' => \$new_master_host,
'new_master_ip=s' => \$new_master_ip,
'new_master_port=i' => \$new_master_port,
'new_master_ssh_port' => \$new_master_ssh_port,
'new_master_user' => \$new_master_user,
'new_master_password' => \$new_master_password
);
exit &main();
sub main {
$ssh_user = defined $ssh_user ? $ssh_user : 'root';
print "\n\nIN SCRIPT TEST====$ssh_user|$ssh_stop_vip==$ssh_user|$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();
&start_arp();
$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() {
`ssh $ssh_user\@$orig_master_host \" $ssh_stop_vip \"`;
}
sub start_arp() {
`ssh $ssh_user\@$new_master_host \" $ssh_Bcast_arp \"`;
}
sub usage {
print
"Usage: master_ip_failover --command=start|stop|stopssh|status --ssh_user=user --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";
}
第九步:创建相关目录
cd /usr/local/bin/scripts
cp master_ip_online_change power_manager /usr/local/bin/
cd /usr/local/bin/
chmod +x master_ip_failover
cd /opt
mkdir /opt/mysql-mha
cd mysql-mha
mkdir mha-manager
mkdir mha-node
[server default]
manager_log=/opt/mysql-mha/manager.log
manager_workdir=/opt/mysql-mha/mha-manager
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
user=manager
password=manager123
port=3306
ping_interval=1
remote_workdir=/opt/mysql-mha/mha-node
repl_user=myslave
repl_password=myslave123
secondary_check_script=/usr/local/bin/masterha_secondary_check -s 192.168.10.21 -s 192.168.10.22
shutdown_script=""
ssh_user=root
[server1]
hostname=192.168.10.20
port=3306
[server2]
hostname=192.168.10.21
port=3306
[server3]
hostname=192.168.10.22
port=3306
~
第十步:在manager节点上测试ssh无密码认证
masterha_check_ssh -conf=/opt/mysql-mha/mysql_mha.cnf
如果正常最后会输出 successfully,如下所示
masterha_check_repl -conf=./mysql_mha.cnf #测试mysql主从连接情况
最后出现 MySQL Replication Health is OK 字样说明正常。如下所示
三台服务器都设置软链接
ln -s /usr/local/mysql/bin/mysqlbinlog /usr/sbin/
第十一步:在 manager 节点上启动 MHA
nohup masterha_manager \
--conf=/opt/mysql-mha/mysql_mha.cnf \
--remove_dead_master_conf \
--ignore_last_failover < /dev/null > /var/log/mha_manager.log 2>&1 &
Master 服务器
第一步:初始化
[root@localhost ~]# systemctl disable --now firewalld
[root@localhost ~]# setenforce 0
[root@localhost ~]# vim /etc/selinux/config
第二步:设置时间同步
vim /etc/chrony.conf
systemctl restart chronyd
第三步:设置主机名
hostnamectl set-hostname mysql1
第四步:修改/etc/my.cnf文件,开启二进制日志和中继日志
vim /etc/my.cnf
server-id = 1
log-bin=mysql-bin
binlog_format=mixed
relay-log=relay-log-bin
relay-log-index=relay-log-bin.index
log-slave-updates = 1
systemctl restart mysqld
第五步:创建mysql和mysqlbinlog的软链接
[root@mysql1 ~]# ln -s /usr/local/mysql/bin/mysql /usr/sbin/
[root@mysql1 ~]# ln -s /usr/local/mysql/bin/mysqladmin /usr/sbin/
第六步:创建并授权数据库主从复制和MHA用户
create user 'myslave'@'192.168.10.%' identified by 'myslave123';
grant replication slave on *.* to 'myslave'@'192.168.10.%';
create user 'manager'@'192.168.10.%' identified by 'manager123';
grant all on *.* to 'manager'@'192.168.10.%';
flush privileges;
第七步:安装MHA依赖的环境
cd /opt/
ls mha/
createrepo mha/
cd mha/
cd /opt
createrepo mha/ #自动生成yum数据库依赖关系
cd mha
----修改目录
vim /etc/yum.repos.d/local.repo
baseurl=file:///opt/mha
----安装依赖包
yum install -y perl-DBD-MySQL \
> perl-Config-Tiny \
> perl-Log-Dispatch \
> perl-Parallel-ForkManager \
> perl-ExtUtils-CBuilder \
> perl-ExtUtils-MakeMaker \
> perl-CPAN
第八步:安装node
cd /opt
rz -E
#mha4mysql-node-0.57.tar.gz
tar xf mha4mysql-node-0.57.tar.gz
cd mha4mysql-node-0.57/
perl Makefile.PL && make && make install
第九步:配置无密码认证
在 mysql1 上配置到数据库节点 mysql2 和 mysql3 的无密码认证
ssh-keygen -t rsa #一路回车
ssh-copy-id 192.168.10.21
ssh-copy-id 192.168.10.22
第十步:在master上面设置虚拟IP
三台服务器都设置软链接
ln -s /usr/local/mysql/bin/mysqlbinlog /usr/sbin/
Slave1 服务器
第一步:初始化
[root@localhost ~]# systemctl disable --now firewalld
[root@localhost ~]# setenforce 0
[root@localhost ~]# vim /etc/selinux/config
第二步:设置时间同步
vim /etc/chrony.conf
systemctl restart chronyd
第三步:设置主机名
hostnamectl set-hostname mysql2
第四步:修改/etc/my.cnf文件,开启二进制日志和中继日志
vim /etc/my.cnf
server-id = 2 #另一个从库此处id号需要更改为3,其他地方不变
log-bin=mysql-bin
binlog_format=mixed
relay-log=relay-log-bin
relay-log-index=relay-log-bin.index
log-slave-updates = 1
systemctl restart mysqld
第五步:创建mysql和mysqlbinlog的软链接
[root@mysql2 ~]# ln -s /usr/local/mysql/bin/mysql /usr/sbin/
[root@mysql2 ~]# ln -s /usr/local/mysql/bin/mysqladmin /usr/sbin/
第六步:创建并授权数据库主从复制和MHA用户
create user 'myslave'@'192.168.10.%' identified by 'myslave123';
grant replication slave on *.* to 'myslave'@'192.168.10.%';
create user 'manager'@'192.168.10.%' identified by 'manager123';
grant all on *.* to 'manager'@'192.168.10.%';
flush privileges;
第七步:
change master to master_host='192.168.10.20', master_port=3306, master_user='myslave', master_password='myslave123', master_log_file='mysql-bin.000001', master_log_pos=1241;
start slave;
第七步:设置从库为只读模式
set global read_only=1;
第八步:安装MHA依赖的环境
cd /opt/
ls mha/
createrepo mha/
cd mha/
cd /opt
createrepo mha/ #自动生成yum数据库依赖关系
cd mha
----修改目录
vim /etc/yum.repos.d/local.repo
baseurl=file:///opt/mha
----安装依赖包
yum install -y perl-DBD-MySQL \
> perl-Config-Tiny \
> perl-Log-Dispatch \
> perl-Parallel-ForkManager \
> perl-ExtUtils-CBuilder \
> perl-ExtUtils-MakeMaker \
> perl-CPAN
第九步:安装node
cd /opt
rz -E
#mha4mysql-node-0.57.tar.gz
tar xf mha4mysql-node-0.57.tar.gz
cd mha4mysql-node-0.57/
perl Makefile.PL && make && make install
第十步:配置无密码认证
在 mysql2 上配置到数据库节点 mysql1 和 mysql3 的无密码认证
ssh-keygen -t rsa #一路回车
ssh-copy-id 192.168.10.20
ssh-copy-id 192.168.10.22
三台服务器都设置软链接
ln -s /usr/local/mysql/bin/mysqlbinlog /usr/sbin/
Slave2 服务器
第一步:初始化
[root@localhost ~]# systemctl disable --now firewalld
[root@localhost ~]# setenforce 0
[root@localhost ~]# vim /etc/selinux/config
第二步:设置时间同步
vim /etc/chrony.conf
systemctl restart chronyd
第三步:设置主机名
hostnamectl set-hostname mysql3
第四步:修改/etc/my.cnf文件,开启二进制日志和中继日志
vim /etc/my.cnf
server-id = 3
log-bin=mysql-bin
binlog_format=mixed
relay-log=relay-log-bin
relay-log-index=relay-log-bin.index
log-slave-updates = 1
systemctl restart mysqld
第五步:创建mysql和mysqlbinlog的软链接
[root@mysql3 ~]# ln -s /usr/local/mysql/bin/mysql /usr/sbin/
[root@mysql3 ~]# ln -s /usr/local/mysql/bin/mysqladmin /usr/sbin/
第六步:
change master to master_host='192.168.10.20', master_port=3306, master_user='myslave', master_password='myslave123', master_log_file='mysql-bin.000001', master_log_pos=1241;
start slave;
第七步:设置从库为只读模式
set global read_only=1;
第八步:安装MHA依赖的环境
cd /opt/
ls mha/
createrepo mha/
cd mha/
cd /opt
createrepo mha/ #自动生成yum数据库依赖关系
cd mha
----修改目录
vim /etc/yum.repos.d/local.repo
baseurl=file:///opt/mha
----安装依赖包
yum install -y perl-DBD-MySQL \
> perl-Config-Tiny \
> perl-Log-Dispatch \
> perl-Parallel-ForkManager \
> perl-ExtUtils-CBuilder \
> perl-ExtUtils-MakeMaker \
> perl-CPAN
第九步:安装node
cd /opt
rz -E
#mha4mysql-node-0.57.tar.gz
tar xf mha4mysql-node-0.57.tar.gz
cd mha4mysql-node-0.57/
perl Makefile.PL && make && make install
第十步:配置无密码认证
在 mysql3 上配置到数据库节点 mysql1 和 mysql2 的无密码认证
ssh-keygen -t rsa #一路回车
ssh-copy-id 192.168.9.150
ssh-copy-id 192.168.9.210
三台服务器都设置软链接
ln -s /usr/local/mysql/bin/mysqlbinlog /usr/sbin/
三、模拟故障切换
此时主库为192.168.10.20a
将该数据库服务器关闭,systemctl stop mysqld
查看日志,发现主库发生了变化
其他服务器所做主从复制的主库也变为192.168.10.21
部署总结
1.采用一主两从架构
2.一主两从先做主从复制
3.给MHA进行登录授权,访问数据库的授权
4.所有数据库节点安装mha node 组件,manager服务器还要安装mha manager 组件
5.所有服务器相互组件做ssh免交互登录
6.manager上准备好VIP故障转移脚本和MHA配置文件
7.在master上创建VIP地址
8.启动MHA进程并做故障转移测试
主从复制步骤
(1)主从服务器先做时间同步
(2)修改主从数据库的配置文件,主库开启二进制日志,从库开启中继日志
(3)在主库创建主从复制的用户,并授予主从复制的权限
(4)在从库使用 change master to 对接主库,并 start slave 开启同步
(5)在从库使用 show slave status\G 查看 IO线程和 SQL线程的状态是否都为 YES