12.6.3 Keepalived + MySQL 主从高可用

Keepalived + MySQL 主从高可用#

架构目标与角色#

  • 目标:提供对外稳定的数据库访问入口,主库故障自动切换到从库,缩短中断时间。
  • 角色:
  • Master:提供写入与读取。
  • Slave:复制主库数据,故障时接管写入。
  • Keepalived:提供 VIP 漂移与健康检查。
  • 可选:ProxySQL/HAProxy 作为读写分离入口并绑定 VIP。

原理草图(VIP 漂移 + 复制)#

文章图片

典型拓扑与前置条件#

  • 节点A:MySQL Master + Keepalived(MASTER)
  • 节点B:MySQL Slave + Keepalived(BACKUP)
  • VIP:10.0.0.100/24
  • 复制:A -> B
  • 前置条件:
  • 主从复制稳定(建议 GTID/半同步)。
  • 业务仅连接 VIP。
  • SSH 免密或脚本本地执行。

安装与基础配置(示例)#

1)安装 Keepalived 与 MySQL(两节点)#

# CentOS/RHEL
yum -y install keepalived mysql-server
systemctl enable mysqld keepalived
systemctl start mysqld

# Ubuntu/Debian
apt -y install keepalived mysql-server
systemctl enable mysql keepalived
systemctl start mysql

2)配置 MySQL 主从(示例使用 GTID)#

  • 主库 /etc/my.cnf 关键项:
[mysqld]
server-id=1
log-bin=mysql-bin
gtid_mode=ON
enforce_gtid_consistency=ON
  • 从库 /etc/my.cnf 关键项:
[mysqld]
server-id=2
log-bin=mysql-bin
gtid_mode=ON
enforce_gtid_consistency=ON
read_only=1
  • 在主库创建复制账号:
CREATE USER 'repl'@'10.0.0.%' IDENTIFIED BY 'Repl@123';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'10.0.0.%';
FLUSH PRIVILEGES;
  • 从库执行复制配置:
CHANGE MASTER TO
MASTER_HOST='10.0.0.11',
MASTER_USER='repl',
MASTER_PASSWORD='Repl@123',
MASTER_AUTO_POSITION=1;
START SLAVE;
  • 复制状态检查:
SHOW SLAVE STATUS\G
-- 预期:
-- Slave_IO_Running: Yes
-- Slave_SQL_Running: Yes
-- Seconds_Behind_Master: 0

Keepalived 配置与健康检查#

1)健康检查脚本(两节点一致)#

  • /etc/keepalived/check_mysql.sh
#!/bin/bash
MYSQL="/usr/bin/mysql -uroot -p'Root@123' -N -e"
# 1. MySQL 进程检查
pgrep -x mysqld >/dev/null || exit 1

# 2. 主库可写 or 从库复制正常
ROLE=$($MYSQL "SELECT @@read_only;")
if [ "$ROLE" = "0" ]; then
  exit 0
fi

# 从库复制检查
IO=$($MYSQL "SHOW SLAVE STATUS\G" | awk '/Slave_IO_Running/{print $2}')
SQL=$($MYSQL "SHOW SLAVE STATUS\G" | awk '/Slave_SQL_Running/{print $2}')
DELAY=$($MYSQL "SHOW SLAVE STATUS\G" | awk '/Seconds_Behind_Master/{print $2}')
[ "$IO" = "Yes" ] && [ "$SQL" = "Yes" ] && [ "${DELAY:-999}" -lt 5 ] || exit 1
exit 0
chmod +x /etc/keepalived/check_mysql.sh

2)Keepalived 配置#

  • MASTER 节点 /etc/keepalived/keepalived.conf
global_defs {
  router_id MYSQL_KA_1
}

vrrp_script chk_mysql {
  script "/etc/keepalived/check_mysql.sh"
  interval 2
  timeout 2
  fall 2
  rise 2
}

vrrp_instance VI_1 {
  state MASTER
  interface eth0
  virtual_router_id 51
  priority 120
  advert_int 1
  nopreempt

  authentication {
    auth_type PASS
    auth_pass 123456
  }

  virtual_ipaddress {
    10.0.0.100/24
  }

  track_script {
    chk_mysql
  }

  notify_master "/etc/keepalived/promote_master.sh"
}
  • BACKUP 节点 /etc/keepalived/keepalived.conf
global_defs {
  router_id MYSQL_KA_2
}

vrrp_script chk_mysql {
  script "/etc/keepalived/check_mysql.sh"
  interval 2
  timeout 2
  fall 2
  rise 2
}

vrrp_instance VI_1 {
  state BACKUP
  interface eth0
  virtual_router_id 51
  priority 100
  advert_int 1
  nopreempt

  authentication {
    auth_type PASS
    auth_pass 123456
  }

  virtual_ipaddress {
    10.0.0.100/24
  }

  track_script {
    chk_mysql
  }

  notify_master "/etc/keepalived/promote_master.sh"
}

3)切换提升脚本#

  • /etc/keepalived/promote_master.sh
#!/bin/bash
MYSQL="/usr/bin/mysql -uroot -p'Root@123' -e"
# 停止复制,解除只读,提升为主库
$MYSQL "STOP SLAVE; SET GLOBAL read_only=0; SET GLOBAL super_read_only=0;"
exit 0
chmod +x /etc/keepalived/promote_master.sh
systemctl restart keepalived

4)预期效果验证#

# 观察 VIP 所在节点
ip a | grep 10.0.0.100

# 模拟主库故障
systemctl stop mysqld

# 预期:VIP 漂移到从库,promote_master.sh 执行
ip a | grep 10.0.0.100

关键命令解释#

  • vrrp_script:周期执行健康检查脚本,返回非 0 则降权触发漂移。
  • priority:优先级,数值高者优先成为 MASTER。
  • nopreempt:避免恢复后的原主库抢占 VIP,降低脑裂风险。
  • notify_master:节点成为 MASTER 时执行脚本,用于提升从库。

常见故障与排错#

1)VIP 不漂移#

# 检查 Keepalived 日志
journalctl -u keepalived -f

# 检查 VRRP 心跳端口(默认 112)
tcpdump -i eth0 vrrp

排查要点:
- virtual_router_idauth_pass 不一致会导致不建立 VRRP。
- 健康检查脚本返回非 0 会持续触发降权。

2)从库未提升为主库#

# 手动验证脚本
bash -x /etc/keepalived/promote_master.sh

排查要点:
- root 密码错误或权限不足。
- read_only 未关闭,导致业务写入失败。

3)复制延迟过大导致误切换#

# 查看延迟
mysql -uroot -p -e "SHOW SLAVE STATUS\G" | grep Seconds_Behind_Master

建议:
- 提高 fall/rise 或放宽延迟阈值。
- 高写入场景启用半同步复制。

运维建议#

  • 定期演练切换与回切。
  • 监控:复制延迟、连接数、慢查询、磁盘 IO。
  • 变更时同时更新健康检查脚本与 MySQL 权限。

练习#

  1. Seconds_Behind_Master 阈值改为 1 秒,观察高峰写入时是否频繁切换。
  2. 主库停机后,验证从库是否自动提升并可写入。
  3. 恢复原主库为从库,完成回切演练并记录切换耗时。