MySQL 主从复制常见报错排查与解决指南
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 TABLE 或 ALTER 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 事务。
- 主库的 Binlog 文件因过期(
- 解决方法:
- 方案 A(推荐,数据一致性好): 重做从库。重新备份主库数据并恢复到从库,重新配置复制位点。
- 方案 B(应急,非 GTID): 获取主库当前最新位点 (
SHOW MASTER STATUS),在从库执行:
注意:此方法会导致从库丢失中间未同步的数据。STOP SLAVE; CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000xxx', MASTER_LOG_POS=4; START SLAVE; - 方案 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。
- 非 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_mode和character_set_server一致。
- 统一结构: 在从库执行
❌ Error 1205: 锁等待超时
- 现象:
Lock wait timeout exceeded - 原因: 从库上有长事务(如大查询、未提交的事务)阻塞了复制线程的应用。
- 解决方法:
- 执行
SHOW PROCESSLIST找到阻塞的线程 ID。 - 执行
KILL <thread_id>杀掉阻塞进程。 - 预防: 设置从库
super_read_only=1,禁止业务应用连接从库进行写操作或长事务读取。
- 执行
❌ Error 1050 / 1051: 表存在或不存在
- 现象:
Table 'xxx' already exists或Unknown 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: YesSlave_SQL_Running: YesSeconds_Behind_Master: 逐渐归零
步骤 4: 数据校验 (重要)
跳过错误后,主从数据可能不一致。建议使用 pt-table-checksum 工具进行校验,并在低峰期修复差异。
5. 预防最佳实践
- 版本一致性: 始终保证 从库版本 >= 主库版本。
- 只读保护: 在从库配置文件 (
my.cnf) 中设置super_read_only = 1,防止人为误写。 - 参数对齐: 确保
binlog_format=ROW,gtid_mode=ON,character_set_server=utf8mb4等关键参数在主从间完全一致。 - Binlog 保留策略: 设置合理的
binlog_expire_logs_seconds(建议至少 7 天),避免因从库长时间宕机导致主库日志被清理。 - 监控报警: 部署监控系统 (Prometheus + Grafana / PMM),对
Seconds_Behind_Master和复制线程状态进行实时报警。 - 定期校验: 定期使用
pt-table-checksum校验主从数据一致性。 - 规范操作: 严禁在从库执行任何 DDL 或 DML 写操作;所有结构变更必须通过主库同步。
- 感谢你赐予我前进的力量
赞赏者名单
因为你们的支持让我意识到写文章的价值🙏
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 龙羽

