前提:针对于InnoDB引擎 行锁讨论
锁机制
MySQL的锁机制可以分为:锁模型(lock mode)和锁类型(lock type)
锁模型(lock mode)
共享锁&排他锁
InnoDB 实现了两种类型的标准行锁:共享(S)锁和排他(X)锁。(下文简称S锁和X锁)
- S锁允许持有该锁的事务读取一行记录,可以同时有多个事务对记录加S锁;
- X锁允许持有该锁的事务更新或删除一行记录,同一时间只能有一个事务加X锁;
- 共享意向锁(IS):指明事务将要获取行的共享锁
- 独占意向锁(IX):指明事务将要获取行的独占锁
测试前提
1、开启lock monitor mysql> show variables like '%innodb_status_output%'; +----------------------------+-------+ | Variable_name | Value | +----------------------------+-------+ | innodb_status_output | OFF | | innodb_status_output_locks | OFF | +----------------------------+-------+ 2 rows in set (0.00 sec) 开启lock monitor mysql> set global innodb_status_output=on; mysql> set global innodb_status_output_locks=on; 2、准备数据 ## 数据库版本:8.0.24
DROP TABLE IF EXISTS `tb2`; CREATE TABLE `tb2` ( `id` int(11) NOT NULL, `c` int(11) NULL DEFAULT NULL, `u` int(11) NULL DEFAULT NULL, `n` int(11) NULL DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE, UNIQUE INDEX `idx_u_unique`(`u`) USING BTREE, INDEX `idx_n_normal`(`n`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; INSERT INTO `tb2` VALUES (10, 11, 12, 13); INSERT INTO `tb2` VALUES (20, 21, 22, 23); INSERT INTO `tb2` VALUES (30, 31, 32, 33);
----------------------------------测试过程省略(太多了)---------------------------------
测试过程中可以通过:
mysql> show engine innodb status\G; 查看加锁情况 或者 mysql> select * from performance_schema.data_locks\G; 查看加锁情况 +----------------------------+-------+ | Variable_name | Value | +----------------------------+-------+ | innodb_print_all_deadlocks | OFF | +----------------------------+-------+ 注意:8.0.24版本没有 information_schema.innodb_lock_waits和information_schema.innodb_locks表了
结论:
RR模式下:
等值select for update/delete/update使用索引类型 | 锁定内容 |
主键(聚簇索引) | 对聚簇索引记录+Record Lock |
唯一索引 | 对辅助索引记录+Record Lock 对聚簇索引记录+Record Lock |
普通索引 | 对相关索引记录+Next-Key Lock(该条记录的前后范围均会被锁住,比如c=23,(13,23],(23,33]均会加锁) 对聚簇索引记录+Record Lock |
不使用索引 | 对聚簇索引全表+ Next-Key Lock |
范围select for/update/delete使用索引类型 | 锁定内容 |
主键(聚簇索引) | 对聚簇索引记录+Record Lock+Next-Key Lock >= =< 或者 对聚簇索引记录+Next-Key Lock > < |
唯一索引 | 对辅助索引记录+Next-Key Lock (该条记录的前后范围均会被锁住,比如u>=4222 and u<=4226 ,(4220 ,4222 ],,(4222,4223],(4223,4226],(4226,4227)均会加锁) 对聚簇索引记录+Record Lock |
普通索引 | 对相关索引记录+Next-Key Lock( 该条记录的前后范围均会被锁住c>43 and c<=433, (43,433],(433,正无穷)均会被锁,而(33,43)这个范围不会被锁,如果c>=43 and c<=433, (33,43]会被锁 ) 对聚簇索引记录+Record Lock |
不使用索引 | 对聚簇索引全表+ Next-Key Lock |
RC模式下:
等值select for update/delete/update使用索引类型 | 锁定内容 |
主键(聚簇索引) | 对聚簇索引记录+Record Lock |
唯一索引 | 对辅助索引记录+Record Lock 对聚簇索引记录+Record Lock |
普通索引 | 对相关索引记录+Recode Lock 对聚簇索引记录+Record Lock |
不使用索引 | 对聚簇索引全表+Recode Lock |
范围select for/update/delete使用索引类型 | 锁定内容 |
主键(聚簇索引) | 对聚簇索引记录+Record Lock |
唯一索引 | 对辅助索引记录+Record Lock 对聚簇索引记录+Record Lock |
普通索引 | 对相关索引记录+Record Lock 对聚簇索引记录+Record Lock |
不使用索引 | 对聚簇索引全表+Record Lock |
个人理解:在RC模式下,由于没有gap锁,也就是间接没有next-key 锁,相当于只有record 锁
附件为:个人对mysql 锁的分类简单记录
标签:加锁,记录,Lock,聚簇,索引,意向锁,SQL,MySQL,Record From: https://www.cnblogs.com/harda/p/16743491.html