MySQL高可用集群部署实战:从主从复制到自动故障切换
本文将详细介绍如何在两台CentOS服务器上部署MySQL高可用集群,实现自动故障检测和切换功能。
目录
环境规划
| 角色 | IP地址 | 主机名 | 说明 |
|---|---|---|---|
| 主节点 | 192.168.4.80 | mysql-db1 | 初始主数据库 |
| 从节点 | 192.168.4.90 | mysql-db2 | 从数据库 + 监控节点 |
| 虚拟IP | 192.168.4.50 | - | 应用连接的浮动IP |
第一步:系统准备
1.1 系统初始化配置
在两台服务器上执行:
# 配置主机名(分别执行)
hostnamectl set-hostname mysql-db1 # 在192.168.4.80执行
hostnamectl set-hostname mysql-db2 # 在192.168.4.90执行
# 创建目录
mkdir -p /data/mysql
mkdir -p /var/log/mha
# 关闭SELinux
setenforce 0
第二步:MySQL主从复制配置
2.1 配置主节点 (192.168.4.80)
编辑MySQL配置文件:
# 备份原配置
cp /etc/my.cnf /etc/my.cnf.backup
# 编辑配置
vi /etc/my.cnf
在[mysqld] 添加:
server-id=1
log-bin=mysql-bin
binlog-format=ROW
gtid-mode=ON
enforce-gtid-consistency=ON
master-info-repository=TABLE
relay-log-info-repository=TABLE
log-slave-updates=ON
binlog-checksum=CRC32
sync-master-info=1
slave-parallel-workers=2
重启MySQL并创建复制用户:
systemctl restart mysqld
mysql -uroot -p'MySQL@123456' -e "
CREATE USER 'repl'@'192.168.4.%' IDENTIFIED BY 'Repl@123456';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.4.%';
FLUSH PRIVILEGES;
SHOW MASTER STATUS\G
2.2 配置从节点 (192.168.4.90)
编辑MySQL配置文件:
cp /etc/my.cnf /etc/my.cnf.backup
vi /etc/my.cnf
在[mysqld] section添加:
server-id=2
log-bin=mysql-bin
binlog-format=ROW
gtid-mode=ON
enforce-gtid-consistency=ON
master-info-repository=TABLE
relay-log-info-repository=TABLE
log-slave-updates=ON
relay-log=mysql-relay-bin
read_only=1
重启MySQL并配置复制:
systemctl restart mysqld
mysql -uroot -p'MySQL@123456' -e "
CHANGE MASTER TO
MASTER_HOST='192.168.4.80',
MASTER_USER='repl',
MASTER_PASSWORD='Repl@123456',
MASTER_AUTO_POSITION=1;
START SLAVE;
SHOW SLAVE STATUS\G
2.3 验证复制状态
在从节点上检查:-p'你的数据库的密码‘
mysql -uroot -p'MySQL@123456' -e "
SHOW SLAVE STATUS\G
" | grep -E "Running|Master_Host"
# 关键指标检查
mysql -uroot -p'MySQL@123456' -e "
SELECT Slave_IO_Running, Slave_SQL_Running
FROM performance_schema.replication_applier_status_by_worker;
"
在主节点创建测试数据:
mysql -uroot -p'MySQL@123456' -e "
CREATE DATABASE mha_test;
USE mha_test;
CREATE TABLE test_table(id INT PRIMARY KEY, name VARCHAR(20));
INSERT INTO test_table VALUES(1, 'test_data');
"

在从节点验证数据同步:
mysql -uroot -p'MySQL@123456' -e "
SELECT * FROM mha_test.test_table;
"
第三步:高可用监控脚本部署
3.1 创建监控脚本
在从节点 (192.168.4.90) 上执行:
# 创建监控脚本
cat > /root/mysql_ha_monitor.sh << 'EOF'
#!/bin/bash
# MySQL高可用监控与自动切换脚本
# 配置变量
MASTER="192.168.4.80"
SLAVE="192.168.4.90"
VIP="192.168.4.50"
MYSQL_USER="root"
MYSQL_PASS="123qqq...A"
LOG_FILE="/var/log/mysql_ha_monitor.log"
# 日志记录函数
log() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> $LOG_FILE
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1"
}
# 检查MySQL节点是否存活
check_mysql() {
if mysql -h $1 -u$MYSQL_USER -p$MYSQL_PASS -e "SELECT 1;" &> /dev/null; then
return 0
else
return 1
fi
}
# 提升从节点为主节点
promote_to_master() {
log "检测到主节点故障,开始提升 $SLAVE 为新的主节点..."
# 1. 停止复制状态
mysql -h $SLAVE -u$MYSQL_USER -p$MYSQL_PASS -e "STOP SLAVE;"
# 2. 重置复制信息
mysql -h $SLAVE -u$MYSQL_USER -p$MYSQL_PASS -e "RESET SLAVE ALL;"
# 3. 重置二进制日志
mysql -h $SLAVE -u$MYSQL_USER -p$MYSQL_PASS -e "RESET MASTER;"
# 4. 关闭只读模式,允许写入
mysql -h $SLAVE -u$MYSQL_USER -p$MYSQL_PASS -e "SET GLOBAL read_only=OFF;"
# 5. 配置虚拟IP (VIP)
ip addr add $VIP/24 dev ens33 2>/dev/null
log "虚拟IP $VIP 已配置到 $SLAVE"
log "故障切换完成!$SLAVE 现已提升为主节点。"
}
# 主监控循环
log "MySQL高可用监控脚本已启动..."
log "监控主节点: $MASTER"
log "备用从节点: $SLAVE"
log "虚拟IP: $VIP"
while true; do
if check_mysql $MASTER; then
# 主节点正常
sleep 5
else
log "警告:无法连接到主节点 $MASTER!"
# 再次确认,避免误判
sleep 5
if ! check_mysql $MASTER; then
# 确认主节点宕机,检查从节点是否健康
if check_mysql $SLAVE; then
promote_to_master
log "监控脚本将在本次切换后退出。请修复原主节点后重新配置并启动监控。"
exit 0
else
log "严重错误:从节点 $SLAVE 也不可用!无法进行自动切换。"
sleep 10
fi
fi
fi
sleep 5
done
EOF
3.2 设置脚本权限和管理工具
# 赋予执行权限
chmod +x /root/mysql_ha_monitor.sh
# 创建日志文件
touch /var/log/mysql_ha_monitor.log
chmod 644 /var/log/mysql_ha_monitor.log
# 创建管理控制脚本
cat > /root/mysql_ha_control.sh << 'EOF'
#!/bin/bash
case "$1" in
start)
echo "启动MySQL高可用监控..."
/root/mysql_ha_monitor.sh &
;;
stop)
echo "停止MySQL高可用监控..."
pkill -f mysql_ha_monitor.sh
;;
status)
echo "检查监控进程状态..."
ps aux | grep mysql_ha_monitor.sh | grep -v grep
if [ $? -eq 0 ]; then
echo "监控正在运行"
tail -10 /var/log/mysql_ha_monitor.log
else
echo "监控未运行"
fi
;;
log)
tail -f /var/log/mysql_ha_monitor.log
;;
vip-add)
ip addr add 192.168.4.50/24 dev ens33
echo "VIP 192.168.4.50 已添加"
;;
vip-remove)
ip addr del 192.168.4.50/24 dev ens33
echo "VIP 192.168.4.50 已移除"
;;
*)
echo "用法: $0 {start|stop|status|log|vip-add|vip-remove}"
exit 1
;;
esac
EOF
chmod +x /root/mysql_ha_control.sh
3.3 启动监控服务
# 启动监控
/root/mysql_ha_control.sh start
# 检查状态
/root/mysql_ha_control.sh status
# 查看实时日志
/root/mysql_ha_control.sh log
第四步:故障切换测试
4.1 测试前状态验证
在从节点 (192.168.4.90) 上执行:
# 确认监控运行状态
/root/mysql_ha_control.sh status
# 检查复制状态
mysql -uroot -p'123qqq...A' -e "SHOW SLAVE STATUS\G" | grep -E "Running|Master_Host"
# 检查VIP状态(应该尚未配置)
ip addr show ens33 | grep 192.168.4.50
4.2 模拟主节点故障
在主节点 (192.168.4.80) 上执行:
# 停止MySQL服务
systemctl stop mysqld
# 确认服务已停止
systemctl status mysqld
4.3 观察自动切换过程
在从节点 (192.168.4.90) 上观察日志:
/root/mysql_ha_control.sh log
4.4 验证切换结果
切换完成后,在从节点验证:
# 检查VIP是否已配置
ip addr show ens33 | grep 192.168.4.50
# 检查复制状态(应该已停止)
mysql -uroot -p'123qqq...A' -e "SHOW SLAVE STATUS\G" | grep -E "Running|Master_Host"
# 检查只读模式是否关闭
mysql -uroot -p'123qqq...A' -e "SELECT @@read_only;"
# 测试写入功能
mysql -uroot -p'123qqq...A' -e "
CREATE DATABASE IF NOT EXISTS failover_test;
USE failover_test;
CREATE TABLE test_table(id INT PRIMARY KEY, test_time TIMESTAMP);
INSERT INTO test_table VALUES(1, NOW());
SELECT * FROM test_table;
"
# 测试VIP连接(从其他机器)
mysql -h192.168.4.50 -uroot -p'123qqq...A' -e "SELECT @@hostname, @@server_id;"
故障恢复流程
当原主节点修复后,需要重新配置主从复制:
-
在原主节点 (192.168.4.80) 上:
systemctl start mysqld mysql -uroot -p'MySQL@123456' -e "RESET MASTER;" -
在当前主节点 (192.168.4.90) 上配置反向复制:
mysql -uroot -p'123qqq...A' -e " CREATE USER 'repl'@'192.168.4.%' IDENTIFIED BY 'Repl@123456'; GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.4.%'; FLUSH PRIVILEGES; SHOW MASTER STATUS\G " -
在原主节点上配置复制:
mysql -uroot -p'MySQL@123456' -e " CHANGE MASTER TO MASTER_HOST='192.168.4.90', MASTER_USER='repl', MASTER_PASSWORD='Repl@123456', MASTER_AUTO_POSITION=1; START SLAVE; " -
重新启动监控:
/root/mysql_ha_control.sh start
# 关键指标检查


# 检查复制状态(应该已停止)
2847



被折叠的 条评论
为什么被折叠?



