问题遇到的现象和发生背景
mysql版本8.0.25, 隔离级别RR
表结构
CREATE TABLE `user`
(
`id` int(0) NOT NULL AUTO_INCREMENT,
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`age` int(0) NULL DEFAULT NULL,
`value` int(0) NOT NULL,
`uni` bigint(0) NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
INDEX `value`(`value`) USING BTREE,
UNIQUE INDEX `uni`(`uni`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
表内记录
id | name | age | value 升序 | uni |
---|---|---|---|---|
626 | Dee Kay | 18 | 3 | 60 |
514 | Justin Casey Howells | 77 | 17 | 32 |
880 | Barb Dwyer | 70 | 42 | 52 |
440 | Ed Venture | 57 | 50 | 76 |
839 | Bjorn Free | 75 | 61 | 80 |
问题相关代码
start transaction;
select * from user where value <= 17 for update;
按加锁规则是给遇到的索引加锁
加锁是这样的
将sql改为
start transaction;
select id from user where value <= 17 for update;
加锁是这样的
从select * 到 select id, 反而多加了个主键的记录锁
个人感觉这id=880这行没必要加索引记录锁, 因为value=42这里已经加上了N-K锁了, 所以id是不能被其他会话更新的, 且只select id, 更新其它字段也可以满足RR隔离级别. 目前不清楚这是BUG还是为了解决其他BUG所作出的优化方案