MySQL多个二级索引并发更新触发死锁

所以第一个事务先根据group_id索引,已经锁住primary id,然后再根据test_id索引,锁定primary id; 第二个事务先根据test_id索引,已经锁住primary id,然后再根据group_id索引,去锁primary id; 所以这样并发更新就可能出现死索引。 MySQL官方也已经确认了此bug: bugs.mysql.com/bug.php?...再看出...
MySQL多个二级索引并发更新触发死锁
删除实例失败,报错db死锁。

事务一:

持有 i-ybsxzr5spk1234567890 锁,去获取 bi-ybrurprssf1234567890 锁;

事务二:

持有 bi-ybrurprssf1234567890 锁,去获取 i-ybsxzr5spk1234567890 锁;

事务一获取 i-ybsxzr5spk1234567890 的锁很好理解,但是这两个事务还要获取 bi-ybrurprssf1234567890 这个锁,看似和这两个update没有关系。

原因是上述两个update语句在执行时,用到了mysql的索引合并。

什么是索引合并( blog.csdn.net/w10140747..., dev.mysql.com/doc/refma...):

索引合并引发死锁( modb.pro/db/58619):

所以第一个事务先根据group_id索引,已经锁住primary id,然后再根据test_id索引,锁定primary id; 第二个事务先根据test_id索引,已经锁住primary id,然后再根据group_id索引,去锁primary id; 所以这样并发更新就可能出现死索引。 MySQL官方也已经确认了此bug: bugs.mysql.com/bug.php?...

再看出问题的两个update语句,where中有两个条件:instance_id 和 deleted_at,并且表结构中有对应两列单独的索引。

解释为什么两个update还要锁 bi-ybrurprssf1234567890,就是因为索引合并中根据 deleted_at 筛选到了 bi-ybrurprssf1234567890 这条记录,并尝试去给这个主键加锁。

表结构复现数据集

gitee.com/chen_zhuohan/...

代码如何避免

总的来说,当你的sql有这种情况,那mysql很有可能用索引合并,就会存在死锁风险:

sql用到了索引合并并非是一个最优的方案,反而证明你的sql需要为索引合并的列建立组合索引。一方面避免上述死锁问题,另一方面索引合并也会有性能损耗,不如直接用组合索引。

2. 使用主键更新列;

更新时where中有主键时,innodb会自动选用PRIMARY索引,而非索引合并。

3. (不推荐)where中的单列索引条件筛选出的结果数很少,比如唯一索引;

4. (不推荐)关闭优化器的index merge优化。

参考文档

MySQL 案例:Update 死锁详解

一次 MySQL 线上死锁分析实战

Reference:2024-09-04
mengvlog 阅读 9 次 更新于 2025-06-20 00:57:49 我来答关注问题0
  •  翡希信息咨询 MySQL多个二级索引并发更新触发死锁

    MySQL多个二级索引并发更新触发死锁的解决方法如下:避免索引合并:建立组合索引:当SQL语句涉及多个索引列时,考虑为这些列建立组合索引。这样可以避免MySQL使用索引合并策略,从而减少死锁的风险。使用主键更新:在更新操作中,如果WHERE子句中包含主键,InnoDB存储引擎会自动选择PRIMARY索引,而不会使用索引合并。...

  • 所以第一个事务先根据group_id索引,已经锁住primary id,然后再根据test_id索引,锁定primary id; 第二个事务先根据test_id索引,已经锁住primary id,然后再根据group_id索引,去锁primary id; 所以这样并发更新就可能出现死索引。 MySQL官方也已经确认了此bug: bugs.mysql.com/bug.php?...再看出...

  •  文暄生活科普 MySQL的3种索引合并优化⭐️or到底能不能用索引?

    案例使用上篇文章的座位表,并分别建立seat_code、student_id两个二级索引。索引合并的优化分成三种方式:index merge intersection, index merge union, index merge sort union。index merge intersection 是用于交集的索引合并,交集往往和查询条件中的and相关。举例这样一条SQL,当不使用索引合并优化时,优...

  •  文暄生活科普 mysqlindexmerge(即索引合并)的意义在于哪里?

    在二级索引中只有索引列相等时才对主键值进行排序,因此大部分使用交集索引合并的场景是等值比较= 开启交集索引合并,查看执行计划 type类型为索引合并,使用到这两个索引,附加信息显示用到交集索引合并,并且还用上覆盖索引不需要回表 由于seat座位表只存在主键seat_id、座位码seat_code、学生ID student_id...

  • 在MySQL中,每个表都有一个聚簇索引,除此之外的非聚簇索引被称为二级索引,也称为辅助索引。以InnoDB为例,每个InnoDB表都包含一个特殊的索引,称为聚簇索引。如果表上定义了主键,那么主键索引就是聚簇索引。如果没有定义主键,MySQL会自动选择第一个唯一索引(unique)且只包含非空列(NOT NULL)...

檬味博客在线解答立即免费咨询

mySQL相关话题

Copyright © 2023 WWW.MENGVLOG.COM - 檬味博客
返回顶部