MySQL 主从切换时 CHANGE MASTER TO
的关键参数必须重设
主库宕机后,若要将原从库提升为主库并让其他从库指向它,
CHANGE MASTER TO不只是改
MASTER_HOST就行。漏掉
MASTER_LOG_FILE和
MASTER_LOG_POS会导致从库拉取错误位置的 binlog,轻则数据跳变,重则复制中断报错
Could not find first log file name in binary log index file。
实操建议:
在原主库宕机前,用SHOW MASTER STATUS记下
File和
Position;若已不可达,则在新主库上执行
SHOW SLAVE STATUS\G查
Relay_Master_Log_File和
Exec_Master_Log_Pos(需确保
Seconds_Behind_Master = 0) 所有待切换的从库执行:
CHANGE MASTER TO MASTER_HOST='new-master-ip', MASTER_PORT=3306, MASTER_USER='repl', MASTER_PASSWORD='xxx', MASTER_LOG_FILE='mysql-bin.000012', MASTER_LOG_POS=198765432;切勿复用旧的
MASTER_AUTO_POSITION=1—— GTID 模式下 failover 更复杂,非 GTID 环境必须显式指定日志文件与位置
手动切换前必须停写并确认从库已追平
很多故障源于“以为追平了”,实际
Seconds_Behind_Master显示为
0但 IO 线程仍在缓存 relay log,SQL 线程尚未执行完。直接切会导致新主库缺失最后一批事务。
验证方法:
在从库执行STOP SLAVE;后,再查
SHOW SLAVE STATUS\G,确认
Slave_IO_Running: No、
Slave_SQL_Running: No,且
Exec_Master_Log_Pos与
Relay_Master_Log_File和原主库宕机前的
SHOW MASTER STATUS完全一致 若原主库已无法访问,可用
SELECT MASTER_POS_WAIT('mysql-bin.000012', 198765432, 30) 在从库上阻塞等待追平(需提前开启 log_slave_updates) 切主前,在原主库上执行
FLUSH TABLES WITH READ LOCK;并记录
SHOW MASTER STATUS,再
UNLOCK TABLES;—— 这是唯一能保证逻辑一致性的停写方式
failover 脚本里漏判 Seconds_Behind_Master = NULL
是高频坑
当从库 IO 线程异常断开(如网络闪断、主库关闭),
Seconds_Behind_Master会变成
NULL而非数字。用
if [ $delay -eq 0 ]类脚本判断是否可切,会直接报错退出或误判为延迟 0 秒。
正确做法:
Shell 脚本中应先检查字段值是否为数字:delay=$(mysql -Nse "SHOW SLAVE STATUS\G" | grep "Seconds_Behind_Master:" | awk '{print \$2}')
if [[ "$delay" =~ ^[0-9]+$ ]] && [ "$delay" -eq 0 ]; then
echo "ready to promote"
fi
监控告警也需区分 NULL(IO 异常)、
0(正常追平)、负数(GTID 模式下可能的特殊情况)
SHOW SLAVE STATUS中
Slave_IO_Running和
Slave_SQL_Running必须同时为
Yes才算健康,缺一不可
切换后务必重置 auto_increment
偏移以防写冲突
原主库恢复后若作为从库重新接入,若未调整
auto_increment_offset和
auto_increment_increment,多主写入时极易出现主键冲突。即使当前是单主架构,也要为后续扩容留余地。
操作建议:
新主库上立即执行:SET GLOBAL auto_increment_increment=2; SET GLOBAL auto_increment_offset=2;原主库重入集群前,将其
auto_increment_offset设为
1,保持两台机器 offset 错开 该设置仅对新生成的自增 ID 生效,已有数据不受影响;但必须在任何写入发生前完成,否则第一条 INSERT 就可能撞上重复值 实际中最容易被忽略的是:切换后没清空旧主库的
relay-log文件,导致它重连时尝试重放早已失效的 relay 日志,报错
Could not parse relay log event entry。每次 promote 后,新主库应运行
RESET SLAVE ALL;彻底清理复制元数据。
