reset slave all是解决relay_log位置偏移导致sql线程停止的唯一推荐操作,它清空relay log状态并删除相关文件;之后须依据主库实时show master status结果执行change master to指定正确binlog位点。

relay_log位置偏移导致SQL线程停止
MySQL从库的SQL_THREAD卡住、Seconds_Behind_Master为NULL或持续增长,常见原因是relay log文件损坏、被误删,或手动执行了CHANGE MASTER TO但没同步更新Relay_Log_File/Relay_Log_Pos——此时SHOW SLAVE STATUS\G里会显示Relay_Log_File指向一个不存在的文件,或Relay_Log_Pos超出该文件实际大小。
- 先确认问题:运行
SHOW SLAVE STATUS\G,重点看Relay_Log_File和Relay_Log_Pos是否合理;用ls -lh查下datadir里是否存在对应relay-log.000xxx文件 - 别直接删
relay-log.*文件——MySQL不会自动重建,反而会让SQL_THREAD拒绝启动 - 如果只是位置越界(比如
Relay_Log_Pos=123456789但文件才1MB),必须重置位点,不能靠跳过错误硬扛
用RESET SLAVE ALL安全清空relay log状态
RESET SLAVE ALL是唯一推荐的起点操作,它会删除master.info、relay-log.info,清空Relay_Log_File和Relay_Log_Pos字段,并移除所有现存relay log文件(注意:不碰binlog,不影响主库)。
- 执行前确保
STOP SLAVE已运行,否则命令会报错 -
RESET SLAVE ALL后,SHOW SLAVE STATUS\G里Relay_Log_File变为空,Relay_Log_Pos变为4,这是正常初始态 - 不要用
RESET SLAVE(不带ALL)——它不清除relay log文件,旧文件残留可能干扰后续同步 - 如果从库启用了
relay_log_purge=OFF,手动清理前先确认磁盘空间,避免RESET SLAVE ALL失败
重新配置MASTER_LOG_FILE和MASTER_LOG_POS
重置之后,必须显式指定主库当前的binlog位置,否则START SLAVE会从头拉取(可能重复执行或漏数据)。关键不是“猜”位置,而是从主库查真实坐标。
- 在主库执行
SHOW MASTER STATUS\G,记下File(如mysql-bin.000123)和Position(如456789) - 在从库执行
CHANGE MASTER TO MASTER_LOG_FILE='<code>mysql-bin.000123', MASTER_LOG_POS=456789;——注意单引号只包文件名,位置值不加引号 - 如果主库开启了GTID,就别设
MASTER_LOG_FILE/MASTER_LOG_POS,改用SET GLOBAL gtid_slave_pos = '<code>uuid:1-100'再CHANGE MASTER TO ... ENABLE_GTID = 1 - 参数写错会导致
START SLAVE后立即报Could not parse relay log event entry——说明位点不合法,得回退重试
验证SQL线程是否真正追上
启动后别只看Slave_IO_Running: Yes和Slave_SQL_Running: Yes,这两个为Yes只代表线程跑起来了,不代表数据一致。
- 检查
Seconds_Behind_Master是否稳定下降并趋近0;若长期为NULL,大概率是relay log又断了,回去查Relay_Log_File是否存在 - 对比主从的
SELECT COUNT(*)或校验表MD5(用pt-table-checksum更准),尤其关注大事务后的表 - 如果从库之前跳过错误(
SET GLOBAL sql_slave_skip_counter = 1),重置位点后这些跳过的语句不会补,数据差异已产生,得人工核对
最麻烦的不是重置操作本身,而是位点来源不可信——比如靠mysqldump --master-data导出的position早已过期,或DBA口头告诉你的文件名拼错了。务必以主库实时SHOW MASTER STATUS为准,多看一眼,少修半天。











