mysql主从同步复制是常用的数据冗余和高可用方案,在实际运行中,受网络波动、数据冲突、配置不当等因素影响,很容易出现主从同步复制错误,导致从库停止同步。本文结合实际遇到的错误案例,讲解完整的排查和解决方法。

错误场景描述
某业务mysql主从架构中,从库突然停止同步,查看从库状态时发现Slave_SQL_Running状态为No,错误提示为重复插入主键数据,具体错误信息如下:
show slave statusG
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.0.10
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000012
Read_Master_Log_Pos: 4567
Relay_Log_File: relay-bin.000005
Relay_Log_Pos: 1234
Relay_Master_Log_File: mysql-bin.000012
Slave_IO_Running: Yes
Slave_SQL_Running: No
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 1062
Last_Error: Error 'Duplicate entry '1001' for key 'PRIMARY'' on query. Default database: 'test_db'. Query: 'INSERT INTO user_info (id, name, age) VALUES (1001, '张三', 25)'
Skip_Counter: 0
Exec_Master_Log_Pos: 1122
Relay_Log_Space: 5678
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 1062
Last_SQL_Error: Error 'Duplicate entry '1001' for key 'PRIMARY'' on query. Default database: 'test_db'. Query: 'INSERT INTO user_info (id, name, age) VALUES (1001, '张三', 25)'
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
Master_UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Master_Info_File: mysql.slave_master_info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State:
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp: 20240501
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set:
Auto_Position: 0
错误排查步骤
1. 确认错误类型
从Last_Errno和Last_Error可以看到错误码为1062,是主键重复错误,说明从库中已经存在id为1001的记录,主库又执行了插入该id的操作,导致从库SQL线程执行失败。
2. 核对主从数据差异
分别查询主从库中user_info表的id为1001的记录,确认数据是否一致:
-- 主库查询 SELECT * FROM test_db.user_info WHERE id = 1001; -- 从库查询 SELECT * FROM test_db.user_info WHERE id = 1001;
查询后发现主库该记录name为张三,age为25,从库该记录name为李四,age为26,说明之前从库数据已经被手动修改过,导致和主库数据冲突。
3. 检查同步配置和日志
确认主库的binlog日志是否正常生成,从库的relay_log是否正常接收,排除日志传输层面的问题:
-- 主库查看binlog状态 SHOW MASTER STATUSG -- 从库查看relay_log状态 SHOW RELAYLOG EVENTS IN 'relay-bin.000005'G
确认日志传输正常后,确定问题根源是从库数据被人为修改,导致主从数据不一致,触发主键冲突错误。
错误解决方案
方法一:跳过当前错误事务(临时应急)
如果业务允许短暂数据不一致,或者该条冲突数据不影响核心业务,可以跳过当前错误的事务,恢复同步:
-- 停止从库同步 STOP SLAVE; -- 跳过1个错误事务 SET GLOBAL sql_slave_skip_counter = 1; -- 重启从库同步 START SLAVE; -- 再次查看从库状态,确认Slave_SQL_Running变为Yes SHOW SLAVE STATUSG
该方法仅适合临时应急,跳过事务后主从数据仍然不一致,需要后续补全数据。
方法二:修复数据后重新同步(彻底解决)
如果要求主从数据完全一致,需要先将从库冲突数据修改为和主库一致,再恢复同步:
-- 从库修改冲突数据,和主库保持一致 UPDATE test_db.user_info SET name = '张三', age = 25 WHERE id = 1001; -- 停止从库同步 STOP SLAVE; -- 重启从库同步 START SLAVE; -- 查看从库状态确认同步正常 SHOW SLAVE STATUSG
如果数据差异较大,也可以从主库导出最新的全量数据,重新导入从库,再配置主从同步。
常见主从复制错误汇总
| 错误码 | 错误原因 | 解决思路 |
|---|---|---|
| 1062 | 主键重复 | 核对主从数据,修复冲突数据或跳过事务 |
| 1032 | 记录不存在 | 检查从库是否缺少对应记录,补全数据 |
| 1236 | binlog读取位置错误 | 重新指定正确的主库binlog文件和位置 |
| 1593 | server-id冲突 | 修改从库server-id,保证主从server-id唯一 |
预防措施
- 禁止直接修改从库数据,从库仅作为只读节点使用
- 定期检查主从同步状态,设置同步状态监控告警
- 主从配置保持一致,避免字符集、时区等配置差异导致数据问题
- 重要操作前备份数据,避免误操作导致数据冲突