能,但须满足从库复制完全追平且无同步状态干扰;需验证Seconds_Behind_Master为0、IO和SQL线程均为Yes、无长事务;切换时按STOP SLAVE→RESET SLAVE ALL→关闭只读→RESET MASTER(非GTID)顺序执行。

主库宕机后,从库能否直接切为主库?
能,但必须满足一个前提:从库的复制已完全追平,且没有残留的同步状态干扰。不是“停掉STOP SLAVE就完事”,而是要确认数据真正一致、位点可定位、角色可重置。
切换前必须验证的三项硬指标
很多人跳过检查,切完才发现丢数据或主键冲突。以下三者缺一不可:
-
Seconds_Behind_Master为0(不能是NULL,也不能是持续波动的小值) -
Slave_IO_Running和Slave_SQL_Running都为Yes - 执行
SHOW PROCESSLIST确认没有长事务、没有未提交的INSERT/UPDATE/DELETE
如果主库已彻底不可达,Seconds_Behind_Master 可能显示为 NULL,此时需结合 Exec_Master_Log_Pos 与主库崩溃前最后记录的 Master_Log_File+Exec_Master_Log_Pos 手动比对——但这一步只有在你提前定期采集主库 SHOW MASTER STATUS 的情况下才可行。
从库提升为主库的关键命令和顺序
顺序错一步,新主库可能无法被其他节点识别,甚至拒绝写入。重点不是“执行什么”,而是“在哪执行”和“为什么不能反过来”:
- 在原从库上执行:
STOP SLAVE→RESET SLAVE ALL(清空master.info、relay-log,避免残留旧主信息) - 紧接着执行:
SET GLOBAL read_only = OFF和SET GLOBAL super_read_only = OFF(只改内存不够,还得同步注释掉配置文件里的read_only=ON) - 必须补上:
RESET MASTER(仅限非 GTID 模式;GTID 模式下严禁执行,否则会清空gtid_executed,导致后续从库无法自动定位) - 检查 binlog 是否已启用:
SHOW VARIABLES LIKE 'log_bin'返回ON;若为OFF,需在/etc/my.cnf中补上log_bin、binlog_format=ROW并重启mysqld
原主库恢复后如何重新接入新主库链路
这不是“配个 IP 就行”的事。最容易出错的是位点指定错误,尤其当新主库在切换后立刻有写入——这时用 SHOW MASTER STATUS 查到的 File 和 Position 已经不是原主库能对接的位置了。
- 推荐使用 GTID:在原主库上执行
CHANGE REPLICATION SOURCE TO SOURCE_HOST='新主IP', SOURCE_AUTO_POSITION = 1,省去手动找位点的麻烦 - 若未启用 GTID,则必须用
MASTER_POS_WAIT在新主库上等待一个确定位置,再把该位置传给原主库——例如在新主库执行SELECT MASTER_POS_WAIT('mysql-bin.000002', 123456789),返回非-1后,才在原主库执行CHANGE MASTER TO ... MASTER_LOG_FILE='mysql-bin.000002', MASTER_LOG_POS=123456789 - 切记:原主库执行
START SLAVE后,必须立刻查SHOW SLAVE STATUS\G,确认Retrieved_Gtid_Set和Executed_Gtid_Set相等(GTID 模式),或Seconds_Behind_Master = 0且无Last_IO_Error/Last_SQL_Error
最常被忽略的,是应用连接池里的 DNS 缓存或连接字符串没更新——数据库切成功了,但业务还在往老主库发请求,结果连不上或者写失败,排查时容易误判为数据库问题。











