relay_log_recovery=on启动报错是因为仅当relay_log_info_repository和master_info_repository均为table且mysql完整重启时才生效,否则因无法解析旧relay-log.info而失败。

relay_log_recovery=ON 为什么启动就报错?
这不是配置写错了,而是它只在特定条件下生效:必须同时满足 relay_log_info_repository=TABLE 和 master_info_repository=TABLE,且 MySQL 是完整重启(不是 service mysql reload)。如果升级前用的是 FILE 模式,升级后即使开了 relay_log_recovery=ON,启动时仍会因无法解析旧的 relay-log.info 文件而失败,报 ER_RPL_RECOVERY_ERROR_READ_RELAY_LOG 或 Failed to open the relay log。
RESET SLAVE ALL 后 START SLAVE 还失败怎么办?
常见错误是跳过了元数据清理步骤,或位点指定错误。安全重置流程如下:
- 先停复制:
STOP SLAVE - 查当前已执行位置:
SHOW SLAVE STATUS\G,记下Exec_Master_Log_Pos和Master_Log_File - 清空元数据表(仅限 TABLE 模式):
RESET SLAVE ALL(注意是ALL,否则mysql.slave_relay_log_info表残留) - 重新指向原位点:
CHANGE MASTER TO MASTER_LOG_FILE='xxx', MASTER_LOG_POS=yyy(必须用上一步的值,不能凭记忆或截图) - 再
START SLAVE
若仍报 ER_SYNC_FAILED_TO_OPEN_RELAY_LOG,检查 /var/lib/mysql/ 下 relay log 文件属主是否为 mysql:mysql,并运行 ausearch -m avc -ts recent | grep mysqld 确认 SELinux 是否拦截。
relay-log.index 损坏导致 Relay_Log_File 为空怎么修?
现象是 SHOW SLAVE STATUS\G 中 Relay_Log_File 字段为空、Seconds_Behind_Master 为 NULL、且无 Last_SQL_Error —— 这说明索引文件损坏,但 relay log 文件本身可能完好。不能 RESET SLAVE,那会丢掉所有位点信息。
手动重建 relay-log.index 的做法:
- 进
/var/lib/mysql/目录,用ls -t mysqld-relay-bin.*列出 relay log 文件,按时间倒序排 - 取最新一个(如
mysqld-relay-bin.000123),写入relay-bin.index(注意文件名要和my.cnf中relay-log参数一致) - 确保该文件权限为
mysql:mysql,然后START SLAVE
GTID 模式下 relay_log_recovery 不起作用?
GTID 模式下 relay_log_recovery 逻辑不同:它不依赖 relay-log.info,而是靠 gtid_executed 和 gtid_purged 推导起点。但如果你在 RESET 后没清 gtid_purged,MySQL 会认为“该执行的都执行过了”,直接停在 Slave_SQL_Running: Yes 但 Seconds_Behind_Master 不动。
关键操作只有两步:
-
RESET SLAVE ALL后,立即执行:SET GLOBAL gtid_purged = 'xxx'(值来自你导入数据时主库的Executed_Gtid_Set) - 再
START SLAVE,否则复制线程不会真正开始拉日志
最容易被忽略的是:relay log 损坏往往不是孤立事件,而是异常断电、kill -9 mysqld 或误删文件的后果;sync_relay_log=1 和 relay_log_recovery=ON 必须配对使用,单开一个效果有限。











