MySQL锁杂谈
创始人
2024-02-17 03:58:41
0

【说明】

1.MySQL版本5.7.37
2.事务隔离级别 REPEATABLE-READ
3.表结构

Create Table: CREATE TABLE `isolation_innodb` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`name` varchar(10) DEFAULT NULL,`money` int(11) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1

4.表数据
在这里插入图片描述




【验证锁等待/事务等待情况】

1.开启事务A , 在事务A中执行 select * from isolation_innodb where id <=13 for update 语句, 并未提交事务 .
2.开启事务B , 在事务B中执行 select * from isolation_innodb where id =10 for update 语句, 此时会被阻塞 .

为了能够观察锁的等待情况, 需要设置 set innodb_lock_wait_timeout=60,让等待时间稍长一些

3.执行以下SQL

SELECT  r.trx_id waiting_trx_id,r.trx_mysql_thread_id waiting_thread,r.trx_query waiting_query,b.trx_id blocking_trx_id,b.trx_mysql_thread_id blocking_thread,b.trx_query blocking_query
FROM information_schema.innodb_lock_waits w
INNER JOIN information_schema.innodb_trx b ON b.trx_id = w.blocking_trx_id
INNER JOIN information_schema.innodb_trx r ON r.trx_id = w.requesting_trx_id;

输出结果如下
在这里插入图片描述

3.1 事务A(515608)阻塞了事务B(515609), 即线程11阻塞了线程12, 线程ID与show processlist 命令显示的ID对应.
3.2 waiting_query表示被阻塞事务B的SQL
3.3 blocking_query表示阻塞事务B(515609)的SQL, 一般情况都是NULL, 因为此SQL大概率已经在事务515608中执行过了.

执行 show processlist 结果如下图

在这里插入图片描述


甚至可以不使用上面的关联语句, 而直接使用以下SQL
SELECT * FROM sys.innodb_lock_waits

输出结果如下


在这里插入图片描述



关于查看事务与锁的相关表和语句如下 :

1.查看事务执行情况
SELECT * FROM information_schema.innodb_trx;

2.查看锁的占用情况 (8.0版本之前)
SELECT * FROM information_schema.innodb_locks;
(8.0版本之后)
SELECT * FROM performance_schema.data_locks;

3.查看锁的等待情况 (8.0版本之前)
SELECT * FROM information_schema.innodb_lock_waits;
(8.0版本之后)
SELECT * FROM performance_schema.data_lock_waits;

set global innodb_status_output_locks=on;
show engine innodb status;



【查看InnoDB锁】

还是以上测试的环境, 通过 show engine innodb status 语句查看事务A加锁的情况

在这里插入图片描述即事务A在isolation_innodb表上加了一把IX锁, 因为RR隔离级别默认在记录上会加Next-Key Lock锁, 如上输出所示, 事务A将 负无穷到id=20的这段区间锁住了.

既然 select * from isolation_innodb where id <=13 for update 为何要一直锁住范围到id=20呢?



查看事务B加锁的情况

在这里插入图片描述

事务B欲通过 select * from isolation_innodb where id=10 for update 语句给id=10的记录加X锁, 但是由于事务A已经将负无穷到id=20的这段区间锁住了, 因此事务B被阻塞.
即便是一条 insert into isolation_innodb values(19,‘F’,2000) 语句, 由于id=19在负无穷到id=20的这段区间, 因此也会被阻塞.




【非索引字段】
事务1
select * from isolation_innodb where name=‘C’ for update; 或 delete from isolation_innodb where name=‘C’; 由于name字段上没有索引, 因此会在主键索引上, 负无穷到正无穷加锁.

事务2
insert into isolation_innodb values(39,‘G’,2000) 会被阻塞



【索引字段加锁,锁定多条数据】
事务1
delete from isolation_innodb where id<=20;

游标会逐条判断, 当id=27时才不满足id<=20, 因此加锁范围是负无穷到id=27

事务2
insert into isolation_innodb values(15,‘G’,2000);
insert into isolation_innodb values(25,‘G’,2000); 都会被阻塞




https://www.yuque.com/infuq/others/ivmss0

相关内容

热门资讯

华宝新能:已制定《市值管理制度... 证券之星消息,华宝新能(301327)12月22日在投资者关系平台上答复投资者关心的问题。 投资者提...
就业网站招聘启事岗位“限男性”... 极目新闻记者 曹雪娇 12月22日,最高人民法院召开新闻发布会,最高人民法院、最高人民检察院在会上联...
宁夏西吉县法官马春刚调解时突发... 西吉县人民法院综合审判庭副庭长马春刚,在调解纠纷时突发心脏病倒在办公桌前,12月12日,经抢救无效不...
台北车站砍人案续:岛内连续发生... 台北车站日前发生持刀砍人案致4死9伤引发岛内外关注。12月22日,南都N视频记者注意到,袭击事件后,...
从创始人驱动到制度驱动,“中国... 导语:随着一代传奇人物陈景河退入幕后,紫金矿业这一庞大的矿业帝国能否续写神话? 李平/作者砺石商业...
“两高”联合发布第三批行政公益... 中新网12月22日电 据“最高人民检察院”微博消息,为进一步发挥典型案例指导引领作用,12月22日,...
福田区举行年度律师大会 《粤港... 深圳新闻网2025年12月22日讯(深圳特区报记者 张玮玮 林清容 通讯员 蔡梓帆 张圳伟)12月1...
浙江天台男子行凶致一死一伤 起... 封面新闻记者 张奕丹 今年5月,浙江省天台县发生一起一死一伤的刑事案件。12月22日,被害人的家属陈...