mysql主从复制报错如何定位_mysql复制错误排查流程

MySQL主从复制报错需先判断IO线程或SQL线程异常,再结合错误码、日志和位点定位问题;重点检查show slave status中的Slave_IO_Running、Slave_SQL_Running及Last_IO_Error/Last_SQL_Error字段。

MySQL主从复制报错,核心是先看“哪条线断了”——IO线程还是SQL线程,再结合错误码和日志定位具体原因。不靠猜,靠状态、日志、位置三步锁定问题。

一、快速判断是IO还是SQL线程出问题

登录从库执行:
mysql> show slave status\G

重点盯住这两行:

  • Slave_IO_Running:显示 NoConnecting → IO线程异常(连不上主库、找不到binlog、权限/网络问题)
  • Slave_SQL_Running:显示 No → SQL线程执行失败(数据冲突、找不到记录、外键约束等)

同时看 Last_IO_ErrorLast_SQL_Error 字段,里面直接带错误码(如1032、1062、1452)和原始报错语句,这是最直接的线索。

二、根据错误码快速归类常见原因

错误码是排查的钥匙,记住这几个高频码:

  • 1032:Can't find record in 'xxx' —— 主库删/改了一条记录,从库没这条数据。常见于手动改过从库、或主从长时间中断后binlog被清理。
  • 1062:Duplicate entry 'X' for key 'PRIMARY' —— 主库插入新行,但从库已有相同主键。说明从库被误写入过数据。
  • 1452:Cannot add or update child row —— 外键约束失败。主库往子表插数据,但父表在从库缺失对应主键值。
  • 1236:Could not find first log file name in binary log index file —— IO线程报错,主库binlog文件已被删除或从库配置的MASTER_LOG_FILE名根本不存在。
  • 2003 / timeout / Connection refused —— 网络层问题:主库防火墙拦了3306、SELinux未关、主库mysqld没监听外网、从库telnet不通主库IP:3306。

三、查日志补全上下文

仅靠show slave status有时信息不够全,需配合:

  • MySQL错误日志
    mysql> show variables like 'log_error';
    查到路径后,用tail -n 50 /var/log/mysqld.log看最近报错细节,尤其关注连接建立、权限校验、文件打开失败类提示。
  • Binlog内容反查(针对SQL线程错误)
    Relay_Master_Log_FileExec_Master_Log_Pos拿到主库binlog名和位点,再在主库执行:
    mysqlbinlog --base64-output=decode-rows -v mysql-bin.000006 | grep -A 10 -B 5 "end_log_pos 254"
    可还原出导致失败的具体SQL语句。

四、验证基础配置是否踩坑

很多“报错”其实源于低级配置失误,建议顺手检查:

  • 主从server-id是否唯一?重复会导致Slave_IO_Running: No且报“server_id of slave is equal to server_id of master”
  • 主库是否开启log-bin?从库my.cnf中是否漏配relay_log
  • 主库是否给从库用户授予REPLICATION SLAVE权限?账号能否从从库IP连上主库?
  • 主从系统时间是否一致?差超过300秒可能影响GTID或证书校验。
  • 防火墙(iptables/firewalld)、SELinux、云平台安全组——是否放行3306且允许双向通信?