1、 什么是死锁

死锁(DeadLock)是指两个或两个以上的事务在执行过程中,因争夺资源而造成相互等待的现象,若无外力作用,它们都将无法进行下去,一直处理等待状态。
image.png

2、 死锁的直观理解

两个事务 A 、B 因争夺资源而相互等待, A 等待 B 释放 id = 2 的锁, B 等待 A 释放 id = 1 的锁

死锁.png

3、 死锁检测

在 MySQL 8 .0 中,增加了一个新的变量 innodb_deadlock_detect , 用于控制 InnoDB 是否执行死锁检测,该参数的默认值为 ON ,即打开死锁检测。

当开启死锁检测时,若发生死锁, InnoDB 会自动回滚一个或多个事务以解决死锁。

  1. SHOW VARIABLES LIKE 'innodb_deadlock_detect';

image.png

4、 锁等待时间

除死锁检测外,还有一个变量 innodb_lock_wait_timeout 也跟死锁有关,它用于设置锁等待时间,默认是 50s, 一旦超过该时间就会报错

SHOW GLOBAL VARIABLES LIKE 'innodb_lock_wait_timeout';

image.png

5、 处理死锁的相关命令

在MySQL的日常使用中,很难免会遇到死锁,除了前面提到的死锁检测、锁等待时间,还有一些命令可以让我们更直观的掌握事务与锁的情况。

-- 查看当前运行的线程
show processlist;

-- 查看当前的事务
select * from information_schema.innodb_trx;

-- 查看当前锁定的事务
select * from information_schema.innodb_locks;

-- 查看当前等锁的事务
select * from information_schema.innodb_waits;

-- 杀掉线程
kill 线程id

6 、SQL语句

CREATE TABLE `dead_lock` (
  `id` int unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(30) COLLATE utf8mb4_general_ci DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

INSERT INTO `dead_lock` VALUES (1, '张三');
INSERT INTO `dead_lock` VALUES (2, '李四');
INSERT INTO `dead_lock` VALUES (3, '王五');
INSERT INTO `dead_lock` VALUES (4, '赵六');

7 、验证锁等待

image.pngimage.png

8、 验证死锁检测

image.png

image.png