You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL 5.7死锁问题求助:附xs_pv表结构详情

MySQL 5.7 异常死锁问题分析与排查

最近在MySQL 5.7环境里碰到了一个棘手的死锁问题,特意把细节和排查思路整理出来,供大家参考:

涉及的表结构

首先贴出问题涉及的xs_pv表完整结构:

CREATE TABLE `xs_pv` ( 
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', 
  `nh_id` int(10) unsigned NOT NULL COMMENT '小说编号', 
  `day` date NOT NULL COMMENT '日期', 
  `pv` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '页面浏览量', 
  `uv` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '独立访客', 
  `name` varchar(50) DEFAULT NULL, 
  PRIMARY KEY (`id`), 
  KEY `nh_id` (`nh_id`), 
  KEY `day` (`day`) 
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;

可能的死锁触发场景

结合InnoDB的锁机制,这个表出现死锁大概率和以下几种情况有关:

  • 并发UPSERT操作冲突:如果业务中频繁对同一nh_id+day组合执行INSERT ... ON DUPLICATE KEY UPDATE,但没有针对这两个字段的联合索引,InnoDB会扫描单列索引产生间隙锁或记录锁冲突
  • 事务操作顺序不一致:不同并发事务的操作顺序颠倒(比如事务1先更新A记录再更新B记录,事务2先更新B记录再更新A记录),极易触发循环等待导致死锁
  • 索引使用不合理:当前表只有nh_id和day的单列索引,当查询/更新同时用到这两个字段时,可能走非最优索引,导致锁的范围被无端扩大

排查与解决建议

  1. 提取死锁核心信息:执行命令 SHOW ENGINE INNODB STATUS;,在输出的LATEST DETECTED DEADLOCK区块里,能看到死锁涉及的事务、SQL语句、锁类型等关键细节,这是定位问题的核心依据
  2. 添加针对性联合索引:如果业务逻辑中经常基于nh_id和day做更新/查询,建议创建联合索引 KEY idx_nh_day (nh_id, day),让InnoDB精准定位记录,大幅缩小锁的范围
  3. 优化事务执行逻辑:尽量缩短事务时长,避免在事务中执行无关操作;同时统一所有并发事务的操作顺序,比如都先处理nh_id较小的记录,再处理较大的
  4. 调整UPSERT逻辑:如果是INSERT ... ON DUPLICATE KEY UPDATE引发的死锁,可以拆分为“先查询(加FOR UPDATE锁)再更新/插入”的逻辑,同时严格控制事务范围

内容的提问来源于stack exchange,提问作者David

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:17:34