tips:
以下测试如无特殊说明,隔离级别均为 MySQL 默认的 REPEATABLE READ 级;
测试使用的 MySQL 版本为 8.0.43;
docker exec -it mysql /bin/bash
mysql -h127.0.0.1 -P3306 -uroot -p123456
一、分析前的一些准备工作
如何查看一个连接持有哪些锁
你可以使用下面的 SQL 语句来查询指定的连接持有哪些锁
-- 获取当前连接的 connection id
SELECT CONNECTION_ID() INTO @connection_id;
-- 根据 connection id 查询指定连接持有的锁
SELECT t2.*
FROM information_schema.innodb_trx t1
JOIN performance_schema.data_locks t2 ON t1.trx_id = t2.ENGINE_TRANSACTION_ID
WHERE t1.trx_mysql_thread_id = @connection_id
;
在分析死锁 Case 时候,你可能会需要关闭死锁检测、延长锁超时时限来观察锁的情况:
SET GLOBAL innodb_deadlock_detect = OFF;
SET GLOBAL innodb_lock_wait_timeout = 9999999999;
-- 实验完成后记得改回去
SET GLOBAL innodb_deadlock_detect = ON;
SET GLOBAL innodb_lock_wait_timeout = 50;
测试数据表、模拟数据
如无特殊说明,这篇文章中的所有 Test Case 都基于下面这个表 t,每次测试完成后都需要重新执行一次下面的 SQL 以重置实验环境。
建表和初始化语句如下:
DROP TABLE IF EXISTS t;
CREATE TABLE t(
id int(11) NOT NULL,
a int(11) DEFAULT NULL,
c int(11) DEFAULT NULL,
d int(11) DEFAULT NULL,
PRIMARY KEY (id),
unique index a(a),
index c (c)
) ENGINE = InnoDB;
insert into t
values (0, 0, 0, 0)
, (5, 5, 5, 5)
, (10, 10, 10, 10)
, (15, 15, 15, 15)
, (20, 20, 20, 20)
, (25, 25, 25, 25);
-
a 字段:唯一索引
-
c 字段:普通索引
评论