目录
前言
MySQL High Availability (MHA) 是一个用于 MySQL 的高可用解决方案,它支持自动故障检测和故障转移。本文将详细介绍如何在三台服务器上部署 MySQL 一主两从的集群,并通过 MHA 实现高可用性以及故障自动切换。
一、环境准备
1.硬件与软件需求
三台Mysql服务器:
Mysql1 (192.168.10.101
):MySQL 主服务器
Mysql2 (192.168.10.102
):MySQL 第一从服务器
Mysql3 (192.168.10.103
):MySQL 第二从服务器
一台 MHA Manager 服务器:
Manager (192.168.10.104
):MHA Manager 服务器
MySQL 5.7 或以上版本、MHA 0.57 版本、Perl 依赖包、EPEL 仓库
2.安装 MySQL 数据库
在 Mysql1、Mysql2 和 Mysql3 上安装 MySQL 数据库。
3.配置 MySQL 一主两从
这里提供的主从复制步骤是简化的概述。对于详细的步骤和配置选项,请参考官方文档或相关教程。
3.1在所有数据库节点上授权两个用户
在所有数据库节点上,我们需要授权两个用户用于主从复制和管理目的:
GRANT REPLICATION SLAVE ON *.* TO 'myslave'@'192.168.10.%' IDENTIFIED BY '123456';
GRANT ALL PRIVILEGES ON *.* TO 'mha'@'192.168.10.%' IDENTIFIED BY 'manager';
这里我们为myslave
用户授予了REPLICATION SLAVE
权限,这允许它作为复制的从属节点。同时,mha
用户被授予了所有权限,以便于管理和维护数据库。
3.2 查看主服务器状态
在主服务器上,我们需要使用 SHOW MASTER STATUS
命令来获取当前的复制状态信息,这对于设置从服务器时非常重要。
SHOW MASTER STATUS;
这将返回主服务器上的文件名和位置,这些信息对于设置从服务器至关重要。输出通常包括以下内容:
File
: 当前正在使用的二进制日志文件名。Position
: 在当前二进制日志文件中的位置。Binlog_Do_DB
: 指定哪些数据库的日志会被记录到二进制日志。Binlog_Ignore_DB
: 指定哪些数据库的日志不会被记录到二进制日志。
3.3在从服务器分别执行同步
在从服务器上,我们需要配置并启动同步进程。首先,使用以下命令来配置从服务器连接到主服务器:
CHANGE MASTER TO
MASTER_HOST='192.168.10.101',
MASTER_USER='myslave',
MASTER_PASSWORD='123456',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=675;
如果之前已经完成了主从复制的设置,则可以跳过此步骤。
接下来,启动从服务器上的同步进程:
START SLAVE;
为了验证同步是否正常运行,可以检查从服务器上的 IO 和 SQL 线程的状态。执行以下命令来查看状态:
SHOW SLAVE STATUS \G;
在输出结果中寻找 Slave_IO_Running
和 Slave_SQL_Running
的值。如果它们都显示为 Yes
,则表示同步正在正常运行。
4.安装 MHA 软件
4.1安装 MHA 依赖的环境
在所有服务器上安装 MHA 依赖的环境:
yum -y 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
4.2安装 node 组件
在所有服务器上安装 node 组件:
tar zxf mha4mysql-node-0.57.tar.gz
cd mha4mysql-node-0.57
perl Makefile.PL
make && make install
4.3安装 manager 组件
在 MHA-manager 服务器上安装 manager 组件:
tar zxf mha4mysql-manager-0.57.tar.gz
cd mha4mysql-manager-0.57
perl Makefile.PL
make && make install
5.配置无密码认证
5.1在 manager 上配置到所有节点的无密码认证
在 MHA-manager 服务器上,我们需要配置到所有数据库节点的无密码SSH认证。首先生成SSH密钥对:
ssh-keygen -t rsa
然后将公钥复制到每个数据库节点上:
ssh-copy-id 192.168.10.101
ssh-copy-id 192.168.10.102
ssh-copy-id 192.168.10.103
这将允许 MHA-manager 服务器无需密码即可登录到数据库节点。
5.2 在数据库节点之间配置无密码认证
我们需要确保数据库节点之间也能进行无密码SSH登录。
Mysql1 需要配置到 192.168.10.102 和 192.168.10.103 的无密码认证:
ssh-keygen -t rsa
ssh-copy-id 192.168.10.102
ssh-copy-id 192.168.10.103
Mysql2 需要配置到 192.168.10.101 和 192.168.10.103 的无密码认证:
ssh-keygen -t rsa
ssh-copy-id 192.168.10.101
ssh-copy-id 192.168.10.103
Mysql3 需要配置到 192.168.10.101 和 192.168.10.102 的无密码认证:
ssh-keygen -t rsa
ssh-copy-id 192.168.10.101
ssh-copy-id 192.168.10.102
完成以上步骤后,所有节点之间的SSH连接都将实现无密码认证。
5.3复制相关脚本
复制MHA管理脚本到/usr/local/bin
目录,并且修改master_ip_failover
脚本以适应你的环境。
cp /root/mha4mysql-manager-0.57/samples/scripts/* /usr/local/bin
vim /usr/local/bin/master_ip_failover
使用下面内容完整替换 master_ip_failover 文件的内容IP 部分更换为自己的 IP
#!/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.8.200/24';
my $key = '1';
my $ssh_start_vip = "/usr/sbin/ifconfig ens33:$key $vip up";
my $ssh_stop_vip = "/usr/sbin/ifconfig ens33:$key down";
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 \"`;
}
sub stop_vip() {
return 0 unless ($ssh_user);
`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";
}
5.4创建 MHA 软件目录并拷贝配置文件
mkdir /etc/masterha
cp /root/mha4mysql-manager-0.57/samples/conf/app1.cnf /etc/masterha
mkdir -p /var/log/masterha/app1
vim /etc/masterha/app1.cnf
编辑app1.cnf
文件:
[server default]
manager_workdir=/var/log/masterha/app1
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
user=mha #MySQL 监控用户
password=manager #MySQL 监控用户的密码
ping_interval=1 #ping 包时间间隔
remote_workdir=/tmp
repl_user=myslave #主从复制用户
repl_password=123456 #主从复制用户的密码
secondary_check_script=/usr/local/bin/masterha_secondary_check -s 192.168.10.102 -s 192.168.10.103
shutdown_script=""
ssh_user=root #SSH 登录用户名
[server1]
hostname=192.168.10.101
port=3306
[server2]
hostname=192.168.10.102
port=3306
candidate_master=1
check_repl_delay=0
[server3]
hostname=192.168.10.103
port=3306
从节点开启二进制日志不然会报错
log-bin=mysql-bin
binlog_format=mixed
5.5测试 SSH 无密码认证
masterha_check_ssh -conf=/etc/masterha/app1.cnf
5.6测试 MySQL 主从连接情况
masterha_check_repl -conf=/etc/masterha/app1.cnf
最后出现 MySQL Replication Health is OK 字样说明正常
如果在执行过程中,有如下报错信息:
Can't exec "mysqlbinlog": No such file or directory at/usr/lib64/perl5/vendor_perl/MHA/BinlogManager.pm line 99.
采用设置软连接的方式解决,三台 MySQL 上都需要执行
ln -s /usr/local/mysql/bin/mysqlbinlog /usr/bin/mysqlbinlog
ln -s /usr/local/mysql/bin/mysql /usr/bin/mysql
5.7首次配置 MHA 的 VIP 地址
在 Mysql1 节点上执行:
ifconfig ens33:1 192.168.10.200
ifconfig ens33:1
VIP 地址不会因为 manager 节点停止 MHA 服务而消失。
启动 MHA
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 &
如果要关闭服务使用masterha_stop --conf=/etc/masterha/app1.cnf 或者直接使用 kill
命令杀死进程
查看 MHA 状态
masterha_check_status --conf=/etc/masterha/app1.cnf
二、模拟 master 故障
1.自动切换
1.1手动 kill 掉当前的 master
在Mysql1 (即当前的 master) 上终止 MySQL 服务:
pkill -9 mysql
观察 MHA manager 日志以确认自动切换是否成功。成功的日志应该包含 "successfully" 字样:
tailf /var/log/masterha/app1/manager.log
1.2检查 VIP 是否被接管
使用 ifconfig
或者 ip addr show
命令检查 Mysql2 (新的 master) 是否接管了 VIP:
ifconfig ens33
2.主库修复后重新加入群集
2.1启动 Mysql1 主库
启动 Mysql1 (原 master) 的 MySQL 服务:
systemctl start mysqld
获取 Mysql1 的当前状态:
SHOW MASTER STATUS;
2.2配置从库同步
在 Mysql1 上配置从 Mysql2 (新的 master) 同步:
CHANGE MASTER TO
MASTER_HOST='192.168.10.102',
MASTER_PORT=3306,
MASTER_LOG_FILE='mysql-log.000001',
MASTER_LOG_POS=154,
MASTER_USER='myslave',
MASTER_PASSWORD='123456';
启动 Mysql1 的从库同步并设置为只读模式:
START SLAVE;
SET GLOBAL read_only=1;
在 Mysql2 上停止同步进程,防止下次作为从库同步时出错:
STOP SLAVE;
RESET SLAVE;
2.手动切换
2.1修改 app1.cnf
文件
将 Mysql1 设置为候选 master:
vim /etc/masterha/app1.cnf
修改内容如下:
[server1]
candidate_master=1
check_repl_delay=0
hostname=192.168.10.101
port=3306
[server2]
hostname=192.168.10.102
port=3306
[server3]
hostname=192.168.10.103
port=3306
2.2手动设置当前的主库 Mysql2 为 dead
使用 masterha_master_switch
命令将 Mysql2 标记为 dead:
masterha_master_switch --conf=/etc/masterha/app1.cnf --master_state=dead --dead_master_host=192.168.10.102
注释 master_ip_online_change
脚本中的第 152 行
注释掉可能导致错误的代码行:
vim /usr/local/bin/master_ip_online_change
注释掉这行
# FIXME_xxx_drop_app_user($orig_master_handler);
2.3重新执行设置新的 master 为 alive 命令
设置 Mysql1 为新的 master:
masterha_master_switch --conf=/etc/masterha/app1.cnf --master_state=alive --new_master_host=192.168.10.101 --orig_master_is_new_slave
2.4确认手动切换成功
成功的日志应包含 "completed successfully" 字样。
至此,MySQL MHA 高可用环境搭建及故障切换完成。
总结
通过上述步骤,实现了 MySQL MHA 高可用环境的部署,能够自动检测和处理主服务器的故障,并支持故障后的自动切换和手动切换操作。这样,即使主服务器发生故障,系统也能够快速恢复服务,保证了业务的连续性和数据的一致性。