MySQL 5.7主从复制必须先跑通,否则Keepalived VIP切换无效;需配置ROW格式、唯一server-id、正确CHANGE MASTER TO、双维度健康检查、bind_address包含VIP、防火墙放行、ip_nonlocal_bind=1及防双写自增策略。

MySQL 5.7 主从复制必须先跑通,否则 Keepalived 只是空中楼阁
双机热备不是配完 Keepalived 就自动高可用——它只管 VIP 切换,数据同步靠的是主从复制。如果 SHOW SLAVE STATUS\G 里 Seconds_Behind_Master 持续不为 0、Slave_IO_Running 或 Slave_SQL_Running 是 No,Keepalived 切过去也是个空壳。
实操建议:
- 主库必须开启
binlog_format = ROW(MySQL 5.7 默认是 STATEMENT,但主从一致性强烈推荐 ROW) - 主库
server-id设为 1,从库设为 2,且全局唯一;重启 mysqld 后用SELECT @@server_id;确认生效 - 创建复制用户时,显式指定
REPLICATION SLAVE权限,不要用GRANT ALL混用 - 从库执行
CHANGE MASTER TO时,MASTER_LOG_FILE和MASTER_LOG_POS必须来自SHOW MASTER STATUS的实时快照,不能凭记忆或旧日志填
Keepalived 配置里最常踩的坑:vrrp_script 检测逻辑太松或太死
很多人写个 mysql -uuser -ppass -e "SELECT 1" 就当健康检查,结果 MySQL 进程挂着但复制已断、或者连接池耗尽,检测却通过了。
更稳妥的做法是检测两个维度:
- MySQL 进程是否存活(用
pgrep mysqld) - 复制是否正常(用
mysql -Nse "SELECT COUNT(*) FROM information_schema.PROCESSLIST WHERE COMMAND='Binlog Dump'"查主库是否有从库连接,或查从库的Slave_IO_Running和Seconds_Behind_Master <= 60)
示例片段(放在 /etc/keepalived/keepalived.conf 的 vrrp_script 块中):
vrrp_script chk_mysql {
script "/usr/local/bin/chk_mysql.sh"
interval 2
weight 2
fall 2
rise 2
}
/usr/local/bin/chk_mysql.sh 要返回 0 才算健康,非 0 就降权——别忘了 chmod +x。
VIP 漂移后应用连不上?大概率是 bind_address 或防火墙没调
MySQL 默认绑定 127.0.0.1 或 0.0.0.0,但 Keepalived 漂移的是一个额外的虚拟 IP(比如 192.168.1.100),如果 bind_address 没包含它,新主节点根本收不到连接请求。
解决方法:
- 主从节点的
my.cnf中设置bind_address = 0.0.0.0(生产环境若需限制,可填多个 IP,用逗号分隔,但必须含 VIP 所在网段) - 确认系统防火墙放行 VIP 对应端口(
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port port="3306" protocol="tcp" accept') - 检查
net.ipv4.ip_nonlocal_bind = 1是否启用(Keepalived 默认需要此内核参数支持绑定非本机 IP)
切换后写操作失败?注意 auto_increment_offset 和 auto_increment_increment
双机热备 ≠ 双写。MySQL 主从本质是单写,Keepalived 只确保同一时刻只有一个主能对外提供写服务。但如果人为在从库执行写入,或配置了错误的自增策略,切主后极易出现主键冲突。
必须在两台机器的 my.cnf 中分别配:
- 节点 A:
auto_increment_offset = 1,auto_increment_increment = 2 - 节点 B:
auto_increment_offset = 2,auto_increment_increment = 2
这样即使意外双写,ID 也不会重叠。不过再次强调:这不是让你双写,而是防配置失误或脑裂时的数据错乱。
真正难处理的是脑裂场景下两边都以为自己是主、都接受写入——这种状态 Keepalived 无法自动修复,必须人工介入比对 binlog、停写、回滚、重搭从库。配置再严谨,也绕不开这个边界。


















