slave_sql_running: no且last_sql_errno为1205或1213表明sql线程因死锁被中止,需查last_sql_error、exec_master_log_pos是否停滞,并通过show engine innodb status分析死锁现场,确认是否由无主键表或并发逻辑缺陷导致。

SHOW SLAVE STATUS 显示 Slave_SQL_Running: No 且有死锁错误
这不是单纯的“同步延迟”,而是 SQL 线程因死锁被 MySQL 自动中止后卡住。关键信号是 Slave_SQL_Running: No,同时 Seconds_Behind_Master 停滞不动,Last_SQL_Errno 很可能为 1213(Deadlock found when trying to get lock)或 1205(Deadlock found)。此时 SQL 线程已退出,不会自动重试。
直接执行 SHOW SLAVE STATUS\G,重点看三处:
-
Last_SQL_Error字段是否含Deadlock或lock关键词 -
Exec_Master_Log_Pos和Relay_Master_Log_File是否停留在某个固定值不再推进 -
Slave_SQL_Running_State若显示Has read all relay log; waiting for the slave I/O thread to update it,说明 SQL 线程已彻底停摆
从 SHOW ENGINE INNODB STATUS 提取死锁现场
死锁发生在从库回放 binlog 时,所以必须登录从库执行 SHOW ENGINE INNODB STATUS,而不是主库。输出里找 LATEST DETECTED DEADLOCK 段落 —— 它记录的是最近一次在从库上发生的死锁,不是主库的。
重点关注其中两块内容:
- 被回滚的事务(
WE ROLL BACK TRANSACTION (X))执行的是哪条语句,比如UPDATE user_offer SET status=1 WHERE id=123 - 另一个持有锁的事务(
HOLDS THE LOCK(S))执行的是什么语句,常见是REPLACE INTO或INSERT ... ON DUPLICATE KEY UPDATE - 锁类型是否都是
RECORDLOCKS,索引名是否为PRIMARY或某个二级索引 —— 这说明冲突集中在同一张表的相同行范围
确认是否由无主键/隐式 row_id 引发的伪死锁
MySQL 5.7 在 RBR 模式下,如果从库表没有显式主键,InnoDB 会用隐式 row_id 定位行。但主从各自维护该计数器,导致回放时 UPDATE 找不到目标行,报错 1032(Can't find record),有时日志会误标为锁等待或死锁现象。
快速验证方法:
- 查从库对应表:
SHOW CREATE TABLE `disc`.`user_offer`,确认是否有PRIMARY KEY或UNIQUE KEY - 若缺失,再查
SELECT COUNT(*) FROM information_schema.INNODB_SYS_TABLES WHERE NAME LIKE 'disc/user_offer',确认表引擎确实是 InnoDB - 若无主键,
Last_SQL_Errno更可能是1032而非1213,但错误日志里可能混写 “waiting for lock” 字样,造成误判
跳过死锁事务前必须检查 GTID 或位点一致性
不能无脑执行 SET GLOBAL sql_slave_skip_counter = 1,尤其在 GTID 模式下该命令无效。先确认复制模式:
- 若
gtid_mode = ON,看Retrieved_Gtid_Set和Executed_Gtid_Set差值。跳过需用SET GTID_NEXT='xxx-xxx-xxx:nnn'; BEGIN; COMMIT; SET GTID_NEXT='AUTOMATIC'; - 若为传统 file+pos 模式,记下当前
Relay_Master_Log_File和Exec_Master_Log_Pos,跳过后用CHANGE MASTER TO MASTER_LOG_FILE='...', MASTER_LOG_POS=...手动对齐 - 跳过之后立即执行
START SLAVE,并立刻查SHOW PROCESSLIST确认 User 为system user的线程状态是否变为Reading event from the relay log
真正容易被忽略的是:死锁往往暴露的是底层设计问题 —— 比如多个服务并发写同一张配置表,或业务代码未按固定顺序访问多张表。单次跳过能恢复同步,但不改逻辑,下周还会触发。











