Skip to content

Commit

Permalink
案例18增加测试脚本
Browse files Browse the repository at this point in the history
  • Loading branch information
aneasystone committed Apr 27, 2019
1 parent 89add1f commit 4a8002a
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 34 deletions.
73 changes: 40 additions & 33 deletions 18.md
Original file line number Diff line number Diff line change
@@ -1,75 +1,82 @@
delete-wait-lock_mode X locks rec but not gap waiting-vs-insert-wait-lock-mode-s-holds-lock-mode-x-locks-rec-but-not-gap
delete-wait-lock-mode-x-locks-rec-but-not-gap-vs-insert-wait-lock-mode-s-holds-lock-mode-x-locks-rec-but-not-gap
===

## 死锁特征

1. lock_mode X locks rec but not gap waiting
1. delete WAITING FOR lock_mode X locks rec but not gap
2. insert WAITING FOR lock mode S, HOLDS lock_mode X locks rec but not gap

## 死锁日志
```
------------------------
LATEST DETECTED DEADLOCK
------------------------
2019-04-21 22:39:55 0x70000851d000
2019-04-26 23:52:06 0x7fcb04122700
*** (1) TRANSACTION:
TRANSACTION 11158, ACTIVE 12 sec starting index read
TRANSACTION 2290, ACTIVE 0 sec starting index read
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 1136, 1 row lock(s)
MySQL thread id 23, OS thread handle 123145442168832, query id 491 localhost 127.0.0.1 root updating
delete from t4 where a = 1
MySQL thread id 5, OS thread handle 140509923120896, query id 861 localhost root updating
delete from t18 where id = 4
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 68 page no 3 n bits 72 index PRIMARY of table `aliyun`.`t4` trx id 11158 lock_mode X locks rec but not gap waiting
Record lock, heap no 2 PHYSICAL RECORD: n_fields 3; compact format; info bits 32
0: len 4; hex 80000001; asc ;;
1: len 6; hex 000000002b95; asc + ;;
2: len 7; hex 6700000199033d; asc g =;;
RECORD LOCKS space id 24 page no 3 n bits 80 index PRIMARY of table `dldb`.`t18` trx id 2290 lock_mode X locks rec but not gap waiting
Record lock, heap no 5 PHYSICAL RECORD: n_fields 3; compact format; info bits 32
0: len 4; hex 00000004; asc ;;
1: len 6; hex 0000000008f1; asc ;;
2: len 7; hex 7a000001ce01ca; asc z ;;
*** (2) TRANSACTION:
TRANSACTION 11157, ACTIVE 16 sec inserting
TRANSACTION 2289, ACTIVE 0 sec inserting
mysql tables in use 1, locked 1
3 lock struct(s), heap size 1136, 2 row lock(s), undo log entries 1
MySQL thread id 22, OS thread handle 123145441890304, query id 492 localhost 127.0.0.1 root update
insert into t4(a) values(1)
MySQL thread id 4, OS thread handle 140509923387136, query id 862 localhost root update
insert into t18 (id) values (4)
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 68 page no 3 n bits 72 index PRIMARY of table `aliyun`.`t4` trx id 11157 lock_mode X locks rec but not gap
Record lock, heap no 2 PHYSICAL RECORD: n_fields 3; compact format; info bits 32
0: len 4; hex 80000001; asc ;;
1: len 6; hex 000000002b95; asc + ;;
2: len 7; hex 6700000199033d; asc g =;;
RECORD LOCKS space id 24 page no 3 n bits 80 index PRIMARY of table `dldb`.`t18` trx id 2289 lock_mode X locks rec but not gap
Record lock, heap no 5 PHYSICAL RECORD: n_fields 3; compact format; info bits 32
0: len 4; hex 00000004; asc ;;
1: len 6; hex 0000000008f1; asc ;;
2: len 7; hex 7a000001ce01ca; asc z ;;
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 68 page no 3 n bits 72 index PRIMARY of table `aliyun`.`t4` trx id 11157 lock mode S waiting
Record lock, heap no 2 PHYSICAL RECORD: n_fields 3; compact format; info bits 32
0: len 4; hex 80000001; asc ;;
1: len 6; hex 000000002b95; asc + ;;
2: len 7; hex 6700000199033d; asc g =;;
RECORD LOCKS space id 24 page no 3 n bits 80 index PRIMARY of table `dldb`.`t18` trx id 2289 lock mode S waiting
Record lock, heap no 5 PHYSICAL RECORD: n_fields 3; compact format; info bits 32
0: len 4; hex 00000004; asc ;;
1: len 6; hex 0000000008f1; asc ;;
2: len 7; hex 7a000001ce01ca; asc z ;;
*** WE ROLL BACK TRANSACTION (1)
------------
```

## 表结构

```sql
CREATE TABLE `t4` (
`a` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`a`)
) ENGINE=InnoDB
CREATE TABLE `t18` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
```

初始数据:

```sql
insert into t4(a) values(1);
INSERT INTO `t18`(`id`) VALUES (1);
INSERT INTO `t18`(`id`) VALUES (2);
INSERT INTO `t18`(`id`) VALUES (3);
INSERT INTO `t18`(`id`) VALUES (4);
INSERT INTO `t18`(`id`) VALUES (5);
INSERT INTO `t18`(`id`) VALUES (6);
INSERT INTO `t18`(`id`) VALUES (7);
INSERT INTO `t18`(`id`) VALUES (8);
```

## 重现步骤

| Session 1 | Session 2 |
| --------- | --------- |
|delete from t4 where a = 1;//ok, 0 rows affected||
||delete from t4 where a = 1; //wating,被阻塞|
|insert into t4 values(1);//Query OK, 1 row affected (0.01 sec)||
|delete from t18 where id = 4;//ok, 0 rows affected||
||delete from t18 where id = 4; //wating,被阻塞|
|insert into t18 values(4);//Query OK, 1 row affected (0.01 sec)||
| | ERROR 1213 (40001): Deadlock found when trying to get lock;|

## 分析
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
|insert|insert|lock_mode X locks gap before rec insert intention|lock_mode X locks gap before rec insert intention|lock_mode X locks gap before rec|14|
|insert|insert|lock_mode X insert intention|lock_mode X insert intention|lock_mode S|2|
|insert|insert|lock mode S|lock_mode X locks gap before rec insert intention|lock_mode X locks rec but not gap|15|
|delete|insert|lock_mode X locks rec but not gap|lock mode S|lock_mode X locks rec but not gap|18|
|delete|delete|lock_mode X|lock mode S|lock_mode X locks rec but not gap|4|
|delete|delete|lock_mode X|lock mode X|lock_mode X locks rec but not gap|6|
|delete|delete|lock_mode X locks rec but not gap|lock_mode X|lock_mode X|3|
Expand All @@ -24,7 +25,6 @@
|update|update|lock_mode X locks rec but not gap|lock mode S|lock_mode X locks rec but not gap|11|
|update|update|lock_mode X|lock_mode X locks gap before rec insert intention|lock_mode X locks rec but not gap|16|
|update|update|lock_mode X locks gap before rec insert intention|lock_mode X locks gap before rec insert intention|lock_mode X|17|
|delete|insert|lock mode S|lock_mode X locks rec but not gap||18|

表中的语句虽然大多数只列出了 delete 和 insert,但实际上绝大多数的 delete 语句和 update 或 select ... for update 加锁机制是一样的,所以为了避免重复,对于 update 语句就不在一起汇总了(当然也有例外,譬如使用 update 对索引进行更新时加锁机制和 delete 是有区别的,这种情况我会单独列出,如案例 11)。

Expand Down
22 changes: 22 additions & 0 deletions docker/db/t18.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
CREATE DATABASE /*!32312 IF NOT EXISTS*/`dldb` /*!40100 DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci */;

USE `dldb`;

CREATE TABLE `t18` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `t18`(`id`) VALUES (1);
INSERT INTO `t18`(`id`) VALUES (2);
INSERT INTO `t18`(`id`) VALUES (3);
INSERT INTO `t18`(`id`) VALUES (4);
INSERT INTO `t18`(`id`) VALUES (5);
INSERT INTO `t18`(`id`) VALUES (6);
INSERT INTO `t18`(`id`) VALUES (7);
INSERT INTO `t18`(`id`) VALUES (8);

/*
mysqlslap --create-schema dldb -q "begin; delete from t18 where id = 4; insert into t18 (id) values (4); rollback;" --number-of-queries=100000 -uroot -p123456 &
mysqlslap --create-schema dldb -q "begin; delete from t18 where id = 4; rollback;" --number-of-queries=100000 -uroot -p123456 &
*/

0 comments on commit 4a8002a

Please sign in to comment.