innodb 中的死锁 [事务在同一页上有锁]

问题描述 投票:0回答:2

MySQL v8.0.23

下面是“显示引擎 innodb 状态”的输出

最新检测到的死锁

2023-04-13 09:25:19 0x7f65e5d5c700
*** (1) TRANSACTION:
TRANSACTION 667552221, ACTIVE 0 sec inserting
mysql tables in use 1, locked 1
LOCK WAIT 3 lock struct(s), heap size 1136, 2 row lock(s), undo log entries 1
MySQL thread id 3662804, OS thread handle 140095257151232, query id 3727267470 x.x.x.x x.x.x.x admin update
Insert into acl (`id`) values ("456085798018673829")

*** (1) HOLDS THE LOCK(S):
RECORD LOCKS space id 14 page no 198202 n bits 80 index bGhRuWwvrN of table `testdb`.`acl` trx id 667552221 lock_mode X locks gap before rec
Record lock, heap no 10 PHYSICAL RECORD: n_fields 7; compact format; info bits 0



*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 14 page no 198202 n bits 80 index bGhRuWwvrN of table `testdb`.`acl` trx id 667552221 lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 10 PHYSICAL RECORD: n_fields 7; compact format; info bits 0



*** (2) TRANSACTION:
TRANSACTION 667552222, ACTIVE 0 sec inserting
mysql tables in use 1, locked 1
LOCK WAIT 3 lock struct(s), heap size 1136, 2 row lock(s), undo log entries 1
MySQL thread id 3662785, OS thread handle 140056638150400, query id 3727267471 x.x.x.x x.x.x.x admin update
Insert into acl (`id`) values ("456085798018677418")

*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 14 page no 198202 n bits 80 index bGhRuWwvrN of table `testdb`.`acl` trx id 667552222 lock_mode X locks gap before rec
Record lock, heap no 10 PHYSICAL RECORD: n_fields 7; compact format; info bits 0



*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 14 page no 198202 n bits 80 index bGhRuWwvrN of table `testdb`.`acl` trx id 667552222 lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 10 PHYSICAL RECORD: n_fields 7; compact format; info bits 0

如果您阅读“持有锁:”,它会显示两个事务的相同页面号和空间 ID。 t 读取两个事务的“lock_mode X”,这意味着它是一个 x 锁。这是否意味着两个事务都已获得同一页面上的锁定?两个事务如何在同一页上有 x 锁?

此外,两者似乎都在等待授予相同的锁。这会如何导致僵局?

表格定义

    CREATE TABLE `ACL` (
  `id` varchar(255) NOT NULL,
  `tenant_id` varchar(255) NOT NULL,
  `cname` varchar(50) NOT NULL,
  `rce_id` varchar(50) NOT NULL,
  `rce_type` int NOT NULL,
  `aen_id` varchar(50) NOT NULL,
  `prs` varchar(50) NOT NULL,
  `status` enum('ACTIVE','INACTIVE') NOT NULL,
  `elt_deny` tinyint(1) DEFAULT NULL,
  PRIMARY KEY (`id`,`tenant_id`),
  UNIQUE KEY `bGhRuWwvrN` (`rce_id`,`rce_type`,`aen_id`,`prs`,`cname`,`tenant_id`),
  KEY `tenant_id$cname$prs$aen_id` (`tenant_id`,`cname`,`prs`,`aen_id`),
  KEY `FZhIAdwsXu` (`tenant_id`,`cname`,`rce_type`,`prs`,`aen_id`),
  KEY `FZhIAdwsXu123` (`tenant_id`,`cname`,`rce_type`,`aen_id`)
)
mysql innodb deadlock
2个回答
0
投票

“lock_mode X 在记录插入意图等待之前锁定间隙”——听起来像是悲观的“间隙”锁。

456085798018673829和456085798018677418之间没有id吗?然后两个

INSERTs
尝试在同一个“间隙”中添加一行。 InnoDB 不会尝试决定两者是否会发生冲突。

这些插入是长期运行事务的一部分吗?我建议解决这个僵局的最佳方法是看看是否有办法加快交易速度。

并且一如既往,准备好发现死锁并重播已回滚的事务。


0
投票

我遇到了同样的问题,但只有在我将“rewriteBatchedStatements = true”添加到我的jdbc连接后才会发生,请检查您的配置

© www.soinside.com 2019 - 2024. All rights reserved.