必须确认从库已完全追平且无残留状态:slave_io_running和slave_sql_running均为yes、seconds_behind_master=0、exec_master_log_pos最大(或多从库时选gtid最全者),再stop slave、reset master、清理master.info与relay-log.info、启用log-bin并关闭read_only/super_read_only,最后用show master status获取位点配置其他从库。

不能直接“提升”,必须先确认从库数据已完全追平、无残留复制状态,再清理元数据、重置角色、开放写入——跳过任一环节都可能引发双主冲突或数据丢失。
如何判断哪个从库能当新主
别只看 Seconds_Behind_Master = 0,这只能说明 SQL 线程没延迟,不代表 relay log 已全部执行完。真实可用的从库要同时满足:
-
Slave_IO_Running: Yes且Slave_SQL_Running: Yes(IO 和 SQL 线程都在跑) Seconds_Behind_Master: 0-
Exec_Master_Log_Pos值最大(多个从库时比这个,它代表已执行到主库 binlog 的哪个位置) - 若开启 GTID,优先选
Retrieved_Gtid_Set包含最全、Executed_Gtid_Set与之最接近的节点
更稳妥的做法是登录每个从库执行:STOP SLAVE IO_THREAD;,再反复 SHOW PROCESSLIST;,直到看到 Has read all relay log 才算真正追平。
STOP SLAVE 后必须执行 RESET MASTER 而非 RESET SLAVE ALL
RESET SLAVE ALL 只清配置,不删 binlog 文件,也不重置 master_log_file 和 master_log_pos —— 这会导致其他从库 CHANGE MASTER TO 时连错位点。生产环境应:
- 先
STOP SLAVE; - 再
RESET MASTER;(清空所有 binlog 并重置为 mysql-bin.000001,新主从此开始记日志) - 手动删除
master.info和relay-log.info(防止重启后 MySQL 自动拉起旧复制)
注意:RESET MASTER 会清空当前所有 binlog,所以务必确保原主库已彻底离线,否则其他从库无法再从原主同步增量。
my.cnf 配置里最容易漏掉的三项
光改 server-id 不够,以下三处不处理,新主启动后立刻拒绝写入或无法被其他从库识别:
- 取消注释或新增
log-bin = /path/to/mysql-bin(没 binlog 就不是主库) - 注释掉
read_only = ON(否则INSERT/UPDATE/DELETE全部报错:Error 1290) - 注释掉
super_read_only = ON(MySQL 5.7+ 默认启用,比read_only更严格)
改完必须重启 mysqld,仅 SET GLOBAL 修改不持久,下次重启仍失效。
其他从库指向新主时,位点参数不能硬写
别在 CHANGE MASTER TO 里写死 MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=154 —— 新主刚 RESET MASTER 后,第一个事件位置未必是 154(尤其启用了 binlog_checksum 或 gtid_mode=ON)。正确做法:
- 在新主上执行
SHOW MASTER STATUS;,取返回的File和Position - 其他从库执行:
CHANGE MASTER TO MASTER_HOST='new_master_ip', MASTER_USER='repl', MASTER_PASSWORD='xxx', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=154;(这里的 154 是实际查出来的值) - 如果用 GTID,直接
CHANGE MASTER TO MASTER_AUTO_POSITION = 1;,省去位点计算
最后检查 SHOW SLAVE STATUS\G 中 Seconds_Behind_Master 是否持续为 0,而不是只看 Slave_IO_Running 和 Slave_SQL_Running 都是 Yes —— 有些场景下线程显示运行中,但实际卡在权限或表不存在等错误上,Seconds_Behind_Master 才是最终可信指标。











