mha无法自动补齐丢失的binlog数据,仅支持选主、补relay log差异、重配从库;真正数据恢复需依赖宕机主库ssh可达、磁盘完好、master_binlog_dir已配置三个硬条件,并手动用mysqlbinlog -r拉取日志后解析恢复。

主库宕机后,MHA 或其他高可用工具只能帮你选新主、补 relay log 差异、重配从库,**不会自动补齐丢失的 binlog 数据**——这部分必须你手动做,而且得在宕机主库还能 SSH 连上、磁盘完好的前提下才可行。
mysqlbinlog -R 能否拉到缺失 binlog?先确认三个硬条件
这是整个手动补齐的前提。如果任一条件不满足,mysqlbinlog -R 会直接失败,后续所有操作都无意义:
- 宕机主库的物理机仍在运行(不是彻底断电/硬盘报废),SSH 可达
-
mysqld进程虽挂,但 MySQL 数据目录(含mysql-bin.*文件)未损坏、可读 - MHA 配置中已声明
master_binlog_dir,且该路径下有近期 binlog(如/data/mysql/mha/binlog/)
常见错误现象:Can't connect to MySQL server on 'xxx' (111) 或 Failed to read binlog file list,基本就是上述某条没满足。别硬试,先查 ls -l /data/mysql/mha/binlog/ 和 ssh user@old-master ls /data/mysql/mha/binlog/。
解析本地 binlog 时,--skip-gtids 和 --database 是保命参数
从宕机主库拷出的 mysql-bin.000012 文件,直接 mysqlbinlog 解析后不能直接 source 到新主库——里面混着 SET @@SESSION.GTID_NEXT、临时表语句、用户变量赋值,执行必报错。
- 加
--skip-gtids:避免 GTID 冲突(尤其新主库已启用 GTID) - 加
--database=mydb:限定只解析目标库,减少干扰和输出体积 - 加
--base64-output=DECODE-ROWS -v:确保能看清 ROW 格式下的具体字段变更 - 别漏
--start-position:用 MHA failover 日志里给出的起始位置(见下一条),不是新主库当前SHOW MASTER STATUS的位置
示例命令:mysqlbinlog --skip-gtids --database=orders --base64-output=DECODE-ROWS -v --start-position=123456 /data/mysql/mha/binlog/mysql-bin.000012 | mysql -u root -p
CHANGE MASTER TO 的位点必须来自 MHA failover 日志,不是新主库
原主库恢复后要作为 slave 接入,CHANGE MASTER TO 的 MASTER_LOG_FILE 和 MASTER_LOG_POS 绝对不能抄新主库当前的 SHOW MASTER STATUS 输出——那会跳过 failover 瞬间新主库刚接收但还没写入 binlog 的部分事件,导致数据不一致。
- 正确来源:
grep 'All other slaves should start replication from here' /var/log/mha/app1/manager.log - 这条日志明确给出推荐语句,形如:
CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000007', MASTER_LOG_POS=456789 - 这个位置是新主库被提升那一刻的精确 binlog 坐标,所有从库(包括恢复后的原主)必须统一追这个点
如果日志已被轮转删掉,就只能靠人工比对:用 mysqlbinlog 查新主库最新 binlog 开头的 # at 4 和 # at xxx,再结合宕机时间估算,但风险极高。
原主库恢复后,别忘了清理残留复制状态文件
原主库重启后,不能直接 START SLAVE。它残留的 master.info、relay-log.index、relay-log.* 文件会干扰新配置,甚至让 IO 线程连错旧地址。
- 停服务后,手动删掉:
rm -f /var/lib/mysql/master.info /var/lib/mysql/relay-log.* /var/lib/mysql/relay-log.index - 启动 mysqld,再执行
STOP SLAVE; RESET SLAVE ALL;(ALL参数清空所有复制元数据) - 然后才执行从 MHA 日志里抄来的
CHANGE MASTER TO,再START SLAVE
最容易被忽略的是 RESET SLAVE ALL ——漏掉它,SHOW SLAVE STATUS 里可能还显示旧的 Master_Host 和 Seconds_Behind_Master,但实际根本没同步。











