1236错误是IO线程因主库拒绝连接而失败,表现为Slave_IO_Running: No、Last_IO_Error含“Got fatal error 1236”,SQL线程仍为Yes;需检查主库binlog是否存在及位点是否越界,GTID模式下须安全合并gtid_purged后重置。

1236 错误从来不是 SQL 线程报的,而是 IO 线程卡死时显示的错误 —— 你看到 SQL_Running: Yes 但 IO_Running: No,说明问题出在“拉日志”这一步,不是“执行日志”。
为什么 SHOW SLAVE STATUS 里 SQL_Running 是 Yes 却还报 1236?
因为 Got fatal error 1236 是主库拒绝从库 IO 线程连接请求时返回的响应,发生在 TCP 连接建立后、开始读 binlog 之前。此时 SQL 线程还在跑它已有的 relay log,所以状态仍是 Yes;而 IO 线程已经退出,IO_Running 变成 No,Last_IO_Error 才会显示 1236。
常见错误现象:
-
Slave_IO_Running: No+Last_IO_Error: Got fatal error 1236...+SQL_Running: Yes -
Seconds_Behind_Master: NULL(因为没新 relay log 可追) -
Read_Master_Log_Pos停在某个值不动,Master_Log_File对应的文件在主库上查不到
怎么确认是 binlog 文件真没了,还是只是位点越界?
先登录主库,运行 SHOW BINARY LOGS;,对比从库 SHOW SLAVE STATUS\G 中的 Master_Log_File 值。如果该文件名不在列表里,就是被删了;如果在,再检查位点是否合法:
- 用
mysqlbinlog --base64-output=DECODE-ROWS -v /path/to/xxx.bin | tail -10查看文件末尾的end_log_pos - 若
Read_Master_Log_Pos> 最大end_log_pos,说明位点超出文件长度(比如要从 12MB 开始读,但文件只有 10MB) - 注意:每个 binlog 文件固定从 position
4开始,不是 0
GTID 模式下 SET GLOBAL gtid_purged 报错 “gtid_executed is not empty” 怎么办?
这是 GTID 模式修复 1236 最常卡住的点。不能直接 SET GLOBAL gtid_purged = '...',因为 MySQL 强制要求 gtid_executed 为空才能写入 gtid_purged。但 RESET MASTER 会清空本机所有 GTID 记录,风险极高。
安全做法分两步:
- 先停同步:
STOP SLAVE; - 查本机已执行 GTID:
SELECT @@global.gtid_executed;,提取其中属于主库 UUID 的部分(例如主库 UUID 是abc-123,就只取abc-123:1-100这段) - 再查主库
SELECT @@global.gtid_purged;,把两者合并去重,作为新gtid_purged值 - 最后执行:
SET GLOBAL gtid_purged = '合并后的字符串';,再START SLAVE;
漏掉从库自己已执行的 GTID,会导致重复执行事务,引发主键冲突或数据错乱。
传统 file/pos 模式下 CHANGE MASTER TO 指向新 binlog 仍报 1236 怎么办?
说明你指的 MASTER_LOG_FILE 其实也已被主库 purge。不要反复试错,直接验证:
- 在主库执行
SHOW MASTER STATUS;,拿到当前最新File和Position - 确认该
File是否存在于SHOW BINARY LOGS;结果中 - 如果不存在,说明主库 binlog 已断层 —— 此时跳过旧位点没有意义,必须重建从库(
mysqldump或xtrabackup全量恢复) - 如果存在,且
Position是4(每个 binlog 起始位置),再执行CHANGE MASTER TO MASTER_LOG_FILE='xxx', MASTER_LOG_POS=4;
别信“FLUSH LOGS 就能解决”,它只生成新文件,不恢复已删旧文件;也别依赖 slave_skip_counter,它对 1236 完全无效 —— 日志都没拉到,跳什么事件?


















