MySQL 主从复制常见报错排查与解决指南

1. 快速诊断命令

当发现主从复制异常时,请立即在从库执行以下命令:

-- MySQL 5.7 及以下
SHOW SLAVE STATUS\G

-- MySQL 8.0+ 或 MariaDB 10.24+
SHOW REPLICA STATUS\G

重点关注字段:

  • Slave_IO_Running: IO 线程状态(应为 Yes
  • Slave_SQL_Running: SQL 线程状态(应为 Yes
  • Last_IO_Error: IO 线程的具体报错信息
  • Last_SQL_Error: SQL 线程的具体报错信息
  • Seconds_Behind_Master: 主从延迟时间(单位为秒)
  • Retrieved_Gtid_Set / Executed_Gtid_Set: GTID 执行情况(若开启 GTID)

2. 报错速查总表

错误代码 线程类型 关键现象 (Last_Error) 核心原因 推荐解决方案 风险等级
1236 IO Got fatal error 1236 ... log file name ... not found impossible position 1. 主库 Binlog 被清理(过期或手动 purge)。2. 从库请求的位点不存在。3. GTID 事务在主库已 purged。 1. 重做从库(最稳妥)。2. 非 GTID:强制指向主库最新 binlog 位点(会丢数据)。3. GTID:重置 gtid_purged 或重做。 🔴 高
1062 SQL Duplicate entry 'xxx' for key 'PRIMARY' 1. 从库存在脏数据(手动写入)。2. 主从数据之前已不一致。3. 网络延迟导致乱序。 1. 跳过事务sql_slave_skip_counter=1 或 GTID 注入空事务)。2. 删除从库冲突数据后重试。3. 重做从库。 🟠 中
1032 SQL Can't find record in 'table_name' 1. 主库执行 UPDATE/DELETE,但从库无该行。2. 从库漏同步了之前的 INSERT。3. 人为在从库删除数据。 1. 跳过事务。2. 在主库查出该记录,手动 INSERT 到从库。3. 检查并修复数据一致性。 🟠 中
1264 SQL Out of range value for column 'xxx' 1. 主从字段类型/长度不一致。2. 主库数据超出从库字段定义范围。 1. 修正从库表结构 (ALTER TABLE 扩大范围)。2. 临时调整 sql_mode 🟡 低
1265 SQL Data truncated for column 'xxx' 1. 字符长度不足。2. 严格模式下数据截断失败。 1. 修正从库表结构。2. 统一主从 sql_mode 🟡 低
1366 SQL Incorrect string value: '\\xF0\\x9F...' 1. 字符集不一致(主库 utf8mb4,从库 utf8)。2. 从库不支持 Emoji (4字节字符)。 1. 将从库字段/表/库改为 utf8mb4。2. 统一主从 character_set_server 🟡 低
1205 SQL Lock wait timeout exceeded 1. 从库有长事务阻塞了复制线程。2. DDL 操作等待元数据锁 (MDL)。 1. KILL 阻塞的长事务 (SHOW PROCESSLIST)。2. 避免在从库执行长查询或写操作。 🟠 中
1050 SQL Table 'xxx' already exists 1. 有人在从库手动创建了表。2. CREATE TABLE 同步时冲突。 1. 在从库 DROP TABLE 后跳过错误重试。2. 严禁在从库进行 DDL 操作。 🟡 低
1051 SQL Unknown table 'xxx' 1. 有人在从库手动删除了表。2. DROP TABLEALTER TABLE 同步时表已不存在。 1. 在从库手动创建空表结构后重试。2. 跳过错误。 🟡 低
1045 IO Access denied for user 'repl'@'...' 1. 复制账号密码错误。2. 权限被回收或主机限制。 1. 在主库重置密码并授权 REPLICATION SLAVE。2. 在从库 CHANGE MASTER TO ... PASSWORD='新密码' 🟢 低
1130 IO Host '...' is not allowed to connect 1. 主库未授权从库 IP。2. 防火墙阻断。 1. 在主库 GRANT ... TO 'user'@'slave_ip'。2. 检查防火墙和安全组。 🟢 低
2003/2013 IO Lost connection to master 1. 网络波动。2. 主库负载过高或重启。3. 超时参数太短。 1. 检查网络和主库状态。2. 增加 MASTER_CONNECT_RETRY 和超时时间。 🟢 低
1756 SQL Worker failed ... dependency conflict 1. 并行复制 (MTS) 检测到事务依赖冲突。2. 外键或触发器导致并发问题。 1. 临时关闭并行复制 (slave_parallel_workers=0)。2. 调整并行策略。3. 跳过冲突事务。 🟠 中
1193 SQL Unknown system variable 'xxx' 1. 从库版本低于主库。2. 主库使用了新版本特性。 1. 升级从库版本 (必须 >= 主库)。2. 避免在主库使用从库不支持的特性。 🟠 中

风险等级说明:

  • 🔴 : 可能导致数据丢失或不一致,需慎重操作,通常建议重做从库。
  • 🟠 : 可能掩盖数据不一致,需人工介入确认数据正确性。
  • 🟡 : 通常是配置或结构问题,修正后可恢复。
  • 🟢 : 通常是网络或权限配置问题,修正后可恢复。

3. 详细报错解析

3.1 IO 线程错误

IO 线程负责连接主库并拉取 Binlog 日志。若此线程停止,从库将无法获取任何新数据。

❌ Error 1236: Binlog 缺失或位置错误

  • 现象: Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'Could not find first log file name in binary log index file'
  • 原因:
    • 主库的 Binlog 文件因过期(expire_logs_days)或被手动清理(PURGE BINARY LOGS)而删除,但从库仍请求该文件。
    • 从库宕机时间过长,落后主库太多。
    • GTID 模式下,主库已 Purge 了从库需要的 GTID 事务。
  • 解决方法:
    1. 方案 A(推荐,数据一致性好): 重做从库。重新备份主库数据并恢复到从库,重新配置复制位点。
    2. 方案 B(应急,非 GTID): 获取主库当前最新位点 (SHOW MASTER STATUS),在从库执行:
      STOP SLAVE;
      CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000xxx', MASTER_LOG_POS=4;
      START SLAVE;
      
      注意:此方法会导致从库丢失中间未同步的数据。
    3. 方案 C(GTID 模式): 若数据允许重置,可尝试重置 gtid_purged,但操作复杂且高风险,通常建议直接重做从库。

❌ Error 1045 / 1130: 权限与连接拒绝

  • 现象: Access denied for user 'repl'@'...'Host ... is not allowed to connect
  • 原因: 复制账号密码变更、权限回收、IP 白名单限制或防火墙拦截。
  • 解决方法:
    • 在主库检查并重置权限:
      GRANT REPLICATION SLAVE ON *.* TO 'repl_user'@'slave_ip' IDENTIFIED BY 'password';
      FLUSH PRIVILEGES;
      
    • 在从库更新密码:
      STOP SLAVE;
      CHANGE MASTER TO MASTER_PASSWORD='new_password';
      START SLAVE;
      

❌ Error 2003 / 2013: 连接丢失

  • 现象: Lost connection to master during query
  • 原因: 网络不稳定、主库负载过高、超时设置过短。
  • 解决方法:
    • 检查网络连通性。
    • 增加重试次数和超时时间:
      CHANGE MASTER TO MASTER_CONNECT_RETRY=60, MASTER_RETRY_COUNT=86400;
      

3.2 SQL 线程错误

SQL 线程负责在从库执行拉取到的 Binlog 事件。若此线程停止,IO 线程通常仍在运行,但数据不再应用。

❌ Error 1062: 主键冲突

  • 现象: Duplicate entry '123' for key 'PRIMARY'
  • 原因: 从库中存在脏数据(手动插入),导致主库同步过来的 INSERT 失败。
  • 解决方法:
    • 跳过事务(仅应急):
      • 非 GTID: SET GLOBAL sql_slave_skip_counter = 1;
      • GTID: 注入空事务跳过特定 GTID。
    • 修正数据: 删除从库冲突行,然后重启复制。
    • 彻底解决: 重做从库。

❌ Error 1032: 记录不存在

  • 现象: Can't find record in 'table_name' (通常在 UPDATE/DELETE 时发生)
  • 原因: 从库缺少该行数据(之前 INSERT 失败或被删),导致无法更新或删除。
  • 解决方法:
    • 跳过事务(同上)。
    • 补全数据: 在主库找到该行,手动 INSERT 到从库。

❌ Error 1264 / 1265 / 1366: 数据类型与字符集

  • 现象: Out of range value, Data truncated, Incorrect string value
  • 原因: 主从表结构不一致(字段长度、类型、字符集不同)。常见于主库 utf8mb4 存 Emoji,从库 utf8 不支持。
  • 解决方法:
    • 统一结构: 在从库执行 ALTER TABLE 修改字段类型、长度或字符集为 utf8mb4
    • 统一配置: 确保主从 sql_modecharacter_set_server 一致。

❌ Error 1205: 锁等待超时

  • 现象: Lock wait timeout exceeded
  • 原因: 从库上有长事务(如大查询、未提交的事务)阻塞了复制线程的应用。
  • 解决方法:
    • 执行 SHOW PROCESSLIST 找到阻塞的线程 ID。
    • 执行 KILL <thread_id> 杀掉阻塞进程。
    • 预防: 设置从库 super_read_only=1,禁止业务应用连接从库进行写操作或长事务读取。

❌ Error 1050 / 1051: 表存在或不存在

  • 现象: Table 'xxx' already existsUnknown table 'xxx'
  • 原因: 人为在从库手动创建或删除了表,导致 DDL 同步冲突。
  • 解决方法:
    • 手动在从库执行相反操作(Drop 或 Create)以对齐结构。
    • 跳过错误并重试。

3.3 并行复制特有错误

仅在开启多线程复制 (slave_parallel_workers > 0) 时出现。

❌ Error 1756 / 1829: 并行冲突

  • 现象: Worker N failed with error ... dependency conflict
  • 原因: 并行线程在处理有依赖关系的事务(如外键、同一行并发更新)时发生逻辑冲突。
  • 解决方法:
    • 临时降级为单线程:SET GLOBAL slave_parallel_workers = 0;
    • 调整并行策略:SET GLOBAL slave_parallel_type = 'LOGICAL_CLOCK';
    • 跳过冲突事务。

4. 通用修复流程

步骤 1: 确认错误

SHOW SLAVE STATUS\G
-- 记录 Last_IO_Error 和 Last_SQL_Error 的具体内容

步骤 2: 临时跳过错误 (仅用于应急恢复,需谨慎)

非 GTID 模式:

STOP SLAVE;
SET GLOBAL sql_slave_skip_counter = 1;
START SLAVE;

GTID 模式:

STOP SLAVE;
-- 将 'xxx:yyy' 替换为报错中提到的具体 GTID
SET GLOBAL gtid_next = 'xxx:yyy'; 
BEGIN; COMMIT;
SET GLOBAL gtid_next = 'AUTOMATIC';
START SLAVE;

步骤 3: 验证恢复

再次执行 SHOW SLAVE STATUS\G,确认:

  • Slave_IO_Running: Yes
  • Slave_SQL_Running: Yes
  • Seconds_Behind_Master: 逐渐归零

步骤 4: 数据校验 (重要)

跳过错误后,主从数据可能不一致。建议使用 pt-table-checksum 工具进行校验,并在低峰期修复差异。


5. 预防最佳实践

  1. 版本一致性: 始终保证 从库版本 >= 主库版本
  2. 只读保护: 在从库配置文件 (my.cnf) 中设置 super_read_only = 1,防止人为误写。
  3. 参数对齐: 确保 binlog_format=ROW, gtid_mode=ON, character_set_server=utf8mb4 等关键参数在主从间完全一致。
  4. Binlog 保留策略: 设置合理的 binlog_expire_logs_seconds (建议至少 7 天),避免因从库长时间宕机导致主库日志被清理。
  5. 监控报警: 部署监控系统 (Prometheus + Grafana / PMM),对 Seconds_Behind_Master 和复制线程状态进行实时报警。
  6. 定期校验: 定期使用 pt-table-checksum 校验主从数据一致性。
  7. 规范操作: 严禁在从库执行任何 DDL 或 DML 写操作;所有结构变更必须通过主库同步。