不能直接升主,必须经验证(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、设唯一server-id并重启)、切流四步闭环操作。

主库物理损坏时,从库能直接升主吗?
不能无脑执行 STOP SLAVE; RESET SLAVE ALL; 就当新主库用。从库默认开启 read_only=ON,且内部仍保留着复制元数据(master.info、relay-log.info、GTID_EXECUTED 等),直接切流量会出错或被拒绝写入。
更关键的是:从库的 server-id 和 auto.cnf 中的 server-uuid 必须与原主库区分开,否则后续再加新从库会触发复制冲突;若原主库已彻底不可达,还必须清除旧的 GTID_PURGED 或重置 binlog 起始位置,否则新主库无法接受新从库的 CHANGE MASTER TO 请求。
用从库文件直接替换主库数据目录(物理恢复)
这是最快路径,适用于主库磁盘损坏但从库数据完整、业务允许短时中断的场景。核心是“把从库变成主库”,不是“把从库数据导入主库”。
安装、修复、更新或打包一个基于 Python 和 PyMySQL 实现的 Windows `mysql` 命令。适用于用户希望在 PowerShell/CMD 中输入 `mysql` 时重定向到 Python 实现、需要交互式输入 MySQL 连接信息、需要同步到当前用户本地 bin 目录,或需要将该能力封装成可公开复用的 Codex skill。
- 在从库上执行
STOP SLAVE;,确认Seconds_Behind_Master = 0后再操作 - 停掉从库 MySQL:
systemctl stop mysql(或对应 service 命令) - 打包整个数据目录(如
/var/lib/mysql),scp 到原主库机器的相同路径下(先mv /var/lib/mysql /var/lib/mysql.bak备份残留) - 重点改两处配置:
– 修改目标机/var/lib/mysql/auto.cnf,替换其中的server-uuid为新值(可用uuidgen生成)
– 检查目标机my.cnf,确保server-id不与集群中任何节点重复,且read_only=OFF、skip_slave_start=1(防误启复制) - 启动 MySQL:
systemctl start mysql,检查错误日志确认无InnoDB: Database page corruption类报错
启动后必须立刻处理的三件事
物理恢复完只是“能跑”,不是“能用”。以下操作漏一项,后续加从库或故障切换都会失败:
- 执行
RESET SLAVE ALL;:清空所有复制状态和 relay log 文件,避免残留信息干扰 - 执行
SET GLOBAL gtid_purged = '...';(仅 GTID 模式):若原主库已不可查,需用从库的SELECT @@gtid_executed;结果做SET GLOBAL gtid_purged = @@gtid_executed;;若非 GTID 模式,则跳过,但必须确保binlog_format = ROW且log_bin = ON - 创建复制用户并授权:
CREATE USER 'repl'@'%' IDENTIFIED BY 'xxx'; GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%'; FLUSH PRIVILEGES;;注意密码强度和 host 范围要匹配后续从库连接方式
为什么不用 mysqldump 导出再导入?
因为那是逻辑重建,耗时长、锁表久、无法保证大库的秒级一致性。而物理恢复本质是“整盘克隆”,只要从库本身没坏、没延迟,恢复后数据就是主库损坏前最后一刻的精确镜像。
但这个快是有前提的:从库必须是 InnoDB 引擎、未启用压缩表、没有加密表空间、且 innodb_log_file_size 和 innodb_log_files_in_group 参数与目标主机 my.cnf 完全一致——否则 MySQL 启动时会报 InnoDB: The log sequence number in ibdata files does not match 并拒绝启动。

















