MySQL 对带有 UPDATE 语句的 JOINed 表采取独占 (X) 锁?

时间:2021-07-10 00:39:51

标签: mysql innodb deadlock x-lock s-lock

我正在寻找 MySQL InnoDB 上 (1213, 'Deadlock found when trying to get lock; try restarting transaction') 的原因。有死锁的可能吗??

1: insert into TABLE_A ... on duplicate key update where id = N
2: update TABLE_B b set b.name = a.name left join TABLE_A a where a.id = N

我的 Python 应用程序连续发送查询 100,000 次。成功 99%,但有些人陷入僵局。

我的假设:

Query [2]Query [1] 之前到达 MySQL 服务器。

在它们之间添加 sleep(1) 解决了这个问题。现在我需要了解原因。 如果我的假设是正确的,则会发生以下情况:

一个。 [2] 通过 s-lock

获得 left join

B. [1] 等待获取 x-lock 因为 s-lock of [2] 阻止它

c. [2] 被锁定等待 x-lock(我不明白为什么会发生)

你能解释一下死锁的原因吗?


MySQL 是:

Server version: 8.0.19 MySQL Community Server - GPL

查询 1 和 2 处于同一连接中。我将 python MySQLdb 与 autocommit=True

一起使用

整个测试代码:

# preparation
CREATE TABLE `A` (
  `id` int NOT NULL AUTO_INCREMENT,
  `name_a` varchar(45) COLLATE utf8mb4_general_ci DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

CREATE TABLE `B` (
  `id` int NOT NULL AUTO_INCREMENT,
  `id_a` int NOT NULL,
  `name_b` varchar(45) COLLATE utf8mb4_general_ci DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

insert into A (name_a) values ('a1');
insert into B (id_a, name_b) values (1, 'b1');

# verify name_a = a1 and name_b = b1
select * from A a left join B b on b.id_a = a.id;

# Query 1
insert into A (id, name_a) values (1, 'new') on duplicate key update id = 1, name_a = 'new';

# Query 2
update B b left join A a on b.id_a = a.id
set b.name_b = a.name_a
where b.id_a = 1;

# verify name_a and name_b has 'new'
select * from A a left join B b on b.id_a = a.id;

0 个答案:

没有答案
相关问题