根本原因是无索引字段导致行锁退化为临键锁甚至表锁;应通过EXPLAIN确认执行计划类型,为高频查询列建联合索引,并避免在索引列上使用函数。
为什么
会卡住其他事务
根本原因不是锁本身,而是被锁的行没有走索引——MySQL 在无索引字段上执行行锁时,会退化为临键锁(Next-Key Lock),锁住整个范围,甚至可能升级成表级锁。常见于
这类查询,如果
没有索引,哪怕只更新 1 行,也可能堵住全表写入。
实操建议:
用
看执行计划,确认
是
或
,而不是
或
对
、
、
中高频出现的列,优先建联合索引,顺序按「等值查询 → 最左前缀 → 范围查询」排,例如
避免在索引列上做函数操作,
会让索引失效,改用
如何快速定位正在争用的行锁
靠
太难读,真正有用的是
和
的组合查法。它能直接告诉你谁在等、等谁、等哪一行。
实操建议:
执行
找出阻塞中的事务
关联
查
,再反查
得到持锁事务的
用
定位对应线程的 SQL(需开启
)
注意:
字段可能为空或被截断,真实语句要从应用日志或慢查日志里交叉验证
语句没走索引却锁了整张表
这不是 bug,是 MySQL 的乐观假设:当优化器预估扫描行数超过一定比例(通常约 20%),它会放弃使用索引,改走主键聚簇索引全扫——而
在这种情况下会对所有扫描过的主键记录加 X 锁,相当于锁表效果。
MySQL(Linux)
MySQL 9.6.0是面向Linux平台的2026年创新版本,核心架构迎来重大革新。其将外键约束与级联操作从InnoDB引擎层上移至SQL层,确保所有数据变更均被完整记录至Binlog,彻底解决了CDC(变更数据捕获)与主从复制中的数据不一致难题。此外,该版本引入container_aware启动选项以原生适配容器环境,并对审计日志进行了组件化重构,为追求极致数据一致性与云原生体验的开发者提供了全新选择。
下载
实操建议:
检查
中的
值,低于 10 就高度可疑;再看
是否远超实际匹配数
用
更新统计信息,有时旧的统计会导致误判
强制走索引仅作临时排查:
,但别长期依赖 hint
如果业务确实需要低区分度字段(如
只有 3 个值),考虑用冗余字段 + 条件索引,比如加
并建索引,值由应用维护
高并发下
的锁行为
这个语句看似原子,其实分三步:先查唯一键、再判断冲突、最后插入或更新。中间任何一步都可能被其他事务打断,导致死锁或间隙锁膨胀。尤其在批量插入场景,很容易触发
。
实操建议:
确保冲突检测字段(如
)有唯一索引,否则会降级为普通索引,间隙锁范围扩大
批量插入时,按主键或唯一键升序排序后再执行,能显著降低死锁概率
避免在同一个事务里混用
和普通
,尤其是更新同一张表不同条件的行
如果只是防重复插入,且业务允许少量失败,用
更轻量,它不加 S 锁,只加插入意向锁
最常被忽略的一点:间隙锁(Gap Lock)不是“锁住了某条数据”,而是“锁住了某个不存在的空档”。你查不到它,也杀不掉它,只能靠索引设计和查询收敛来规避。一旦出现抖动,先看是不是在没索引的字段上做了范围操作。
SELECT ... FOR UPDATEWHERE status = 'pending'statusEXPLAINtyperefrangeALLindexWHEREORDER BYJOIN(user_id, status, created_at)WHERE DATE(created_at) = '2024-01-01'WHERE created_at >= '2024-01-01' AND created_at SHOW ENGINE INNODB STATUS\Ginformation_schema.INNODB_TRXINNODB_LOCK_WAITSSELECT * FROM information_schema.INNODB_TRX WHERE trx_state = 'LOCK WAIT';INNODB_LOCK_WAITSblocking_trx_idINNODB_TRXtrx_mysql_thread_idSELECT * FROM performance_schema.threads WHERE THREAD_ID = ?performance_schematrx_queryUPDATEUPDATEEXPLAIN FORMAT=JSONfilteredrowsANALYZE TABLEUPDATE t USE INDEX (idx_status) SET ... WHERE status = 'done'statusis_pending TINYINTINSERT ... ON DUPLICATE KEY UPDATELock wait timeout exceededUNIQUE KEY (order_no)INSERT ... ON DUPLICATE KEY UPDATEUPDATEINSERT IGNORE