先看Last_SQL_Error再行动,它直接暴露错误码(如1062主键冲突、1032找不到记录),RBR模式需用mysqlbinlog解析relay log定位真实SQL,1062/1032应优先手动修复而非跳过,GTID下sql_slave_skip_counter失效。

看 Last_SQL_Error 而不是直接 START SLAVE
看到 Slave_SQL_Running: No 或日志里出现 Slave SQL for channel '' 报错,第一反应不是重启线程,而是立刻执行 SHOW SLAVE STATUS\G。关键字段是 Last_SQL_Error——它直接暴露错误码和上下文,比如:Error_code: 1062(主键重复)、Error_code: 1032(找不到记录)、Error_code: 1050(表已存在)、Error_code: 1008(库不存在)。这些错误成因完全不同,跳过前必须先分清类型。
RBR 模式下必须用 mysqlbinlog 解析 relay log
MySQL 5.7+ 默认启用 RBR(binlog_format = ROW),Last_SQL_Error 只显示位置(如 end_log_pos 123456),不显示真实 SQL。这时必须解析从库本地的 relay log:
- 先确认 relay log 文件路径:
ls /var/lib/mysql/*relay*(Docker 环境注意主机名前缀) - 用
mysqlbinlog --base64-output=decode-rows -v --start-position=123400 --stop-position=123500 /var/lib/mysql/relay-log.000001提取失败事务 - 重点看
### UPDATE或### DELETE前后的表名、WHERE 条件,以及@1=对应的字段值 - 如果解析出的语句在从库上手动执行也报错(如
Table 'xxx' doesn't exist),说明 DDL 没同步或顺序错乱
1062 和 1032 错误优先手动修复,不是跳过
Error_code: 1062 和 Error_code: 1032 都是数据不一致的信号,跳过只是掩盖问题:
- 对
1062:先SELECT * FROM table WHERE id = X查从库是否已有冲突行;有则DELETE掉,再START SLAVE - 对
1032:查主库该行是否存在(SELECT ... FROM table WHERE ...),若主库已删,从库补删;若主库未删,说明从库误删,需从备份恢复或回放缺失 binlog -
SET GLOBAL sql_slave_skip_counter = 1在 RBR 下极危险——它可能跳过一个事务里的部分行变更,留下半截脏数据 - GTID 模式下该变量完全失效,必须用
SET GTID_NEXT='xxx:yyy'; BEGIN; COMMIT;插入空事务跳过
检查 server-id 是否重复或配置失效
IO_Running: No 且 Last_IO_Error 含 error 1236 或连接拒绝时,大概率是 server-id 冲突:
- 各节点执行
SELECT @@server_id;,确认非零且全局唯一(不能主从都为 1) -
server-id必须写在[mysqld]段下,写在[client]或[mysqld_safe]下会被忽略 - Docker 或云数据库环境,检查启动脚本是否覆盖了配置;阿里云 RDS 等托管服务通常禁止手动改
server-id - 修改后必须重启 mysqld,并重新执行
CHANGE MASTER TO,否则旧复制上下文仍缓存错误的server-id
实际操作中最容易被忽略的是:RBR 模式下盲目用 sql_slave_skip_counter,以及把 server-id 写错段落却以为配置生效。这两个点一旦出错,后续所有跳过或重试都是无效循环。


















