准备材料
建一张表,数据列不建立索引。并写入1万条数据
CREATE TABLE `identity`.`t2` (
`id` INT NOT NULL COMMENT 'Id',
`a` INT NULL,
PRIMARY KEY (`id`),
KEY `idx_a` (`a`)
);
delimiter //
create procedure gen_data()
begin
declare i int default 0;
set i=0;
start transaction;
while i<10000 do
insert into t2(a) values(i);
set i=i+1;
end while;
commit;
end;
//
delimiter ;
call gen_data();
我的MySQL版本
Your MySQL connection id is 9
Server version: 5.7.43 Homebrew
Copyright (c) 2000, 2023, Oracle and/or its affiliates.
实验步骤
我用的是mysql 客户端,首先在客户端禁掉自动提交事务
set autocommit = 0;
执行update语句,where条件不会命中索引
begin;
update t2 set a =1 where a = 1;
查看innodb 引擎状态,发现刚刚提交的事务锁了23条记录。
SHOW ENGINE INNODB STATUS \G;
打开一个新的session。mysql客户端开了一个session,这个session获取了t2表的锁
mysql -u root -p
a < 1000时,需要等待锁释放,a > 1000时,可以执行成功。说明只是锁了部分记录,并未锁全表。
– 查看正在锁的事务
select * from information_schema.innodb_locks;
发现innodb锁了7号page的数据
附录
一些分析锁的常用mysql命令
– 查询线程执行情况
SELECT * FROM performance_schema.threads
– 查看当前所有事务
select * from information_schema.innodb_trx;
– 查看正在锁的事务
select * from information_schema.innodb_locks;
– 查看等待锁的事务
select * from information_schema.innodb_lock_waits;
– 查看表锁
show open tables where In_use>0;
–查看死锁
show engine innodb status;
- 超时时间查看
SHOW VARIABLES LIKE 'innodb_lock_wait_timeout';