最关键字段是relay_master_log_file、exec_master_log_pos和master_host;前两者标识从库上次成功执行到主库binlog的文件与位置,若该文件在主库已不存在(如被purge或过期清理),则必然触发错误1236。

看 SHOW SLAVE STATUS 里哪几个字段最关键
别一上来就 RESET,先盯住三个值:Relay_Master_Log_File、Exec_Master_Log_Pos 和 Master_Host。前两者合起来就是“从库上次成功执行到主库的哪个文件、哪个位置”。如果 Relay_Master_Log_File 是 mysql-bin.000081,而主库上早没这文件了,那 1236 就是必然结果。
顺手检查 Seconds_Behind_Master:如果是 NULL,且 Slave_IO_Running: No,基本能锁定是 IO 线程卡在拉日志阶段,不是 SQL 执行出错。
-
Master_Log_File和Read_Master_Log_Pos表示 IO 线程当前“想读”的位置,它可能比Exec_Master_Log_Pos超前很多——但只要它指向一个主库已删的文件,就会立刻报 1236 - 如果
Master_Auto_Position: 1,说明走 GTID 模式,此时Relay_Master_Log_File和Exec_Master_Log_Pos就只是历史快照,真正要看的是Retrieved_Gtid_Set和Executed_Gtid_Set
登录主库查 SHOW BINARY LOGS 和磁盘文件是否一致
执行 SHOW BINARY LOGS;,看输出列表里有没有 Relay_Master_Log_File 对应的文件名。没有?那八成是被 PURGE BINARY LOGS 或自动过期删了。再查两个参数:expire_logs_days 和 binlog_expire_logs_seconds(MySQL 8.0.28+ 优先用后者),确认是否设得太小。
如果有,但文件实际不存在:用 ls -l /var/lib/mysql/mysql-bin.000081(路径以 datadir 和 log_bin_basename 配置为准)验证。返回 No such file,就得排查是不是磁盘损坏、配置写错路径,或者被人手动 rm 过。
- 即使文件存在,也要用
mysqlbinlog --base64-output=DECODE-ROWS -v /path/to/file | tail -20查末尾end_log_pos,确认它 ≥Exec_Master_Log_Pos;否则位置越界也会触发 1236 - 注意:主库重启会强制轮转新 binlog 文件,如果从库停太久,旧文件可能已被轮出且未保留足够久
区分 GTID 模式还是传统 file/pos 模式再动手
在主库跑 SELECT @@global.gtid_mode;:返回 ON 就是 GTID 模式,返回 OFF 就是传统模式。这个判断必须做准,混用修复方式等于雪上加霜。
GTID 模式下,RESET MASTER 是高危操作——它会清空 gtid_executed 和 gtid_purged,导致后续报 “master has purged binary logs containing GTIDs that the slave requires”。传统模式下反而可以用 CHANGE MASTER TO MASTER_LOG_FILE='xxx', MASTER_LOG_POS=4 指向最新日志开头(用 SHOW MASTER STATUS 取值),但前提是文件真实存在且位置合法(一般 pos=4 是安全起点)。
- GTID 模式真该做的是合并设置:
SET GLOBAL gtid_purged = 'UUID1:1-370,UUID2:1-2';,这个值必须包含从库自己的gtid_executed+ 主库gtid_purged中属于主库 UUID 的部分 - 从库
SHOW SLAVE STATUS里若Master_Auto_Position: 0但主库已开 GTID,得先STOP SLAVE; CHANGE MASTER TO MASTER_AUTO_POSITION = 1;,否则协议不匹配直接 1236
别漏掉 max_allowed_packet 不一致这个隐形杀手
错误信息里如果带 log event entry exceeded max_allowed_packet,那就不是 binlog 缺失,而是主从参数打架或事务过大。查两边的 max_allowed_packet 值(单位字节),必须一致。升级 MySQL 后尤其容易被默认配置覆盖回 4MB。
MySQL 5.6+ 还有个 slave_max_allowed_packet_size 参数,它控制从库接收 packet 的上限,通常比 max_allowed_packet 更大,建议显式设为 1G 并重启从库服务生效。
- 主库产生大事务(比如
LOAD DATA INFILE或大表INSERT ... SELECT)时,binlog event 可能远超 4MB,从库收不下就直接中断并报 1236 -
max_allowed_packet不是 SET GLOBAL 就能热生效的,改完必须重启 MySQL,否则无效











