要找到下一行键锁的范围,我做了一些测试。我发现它与mysql的doc。
中的下一行键锁的描述不同在文件中,它说:
假设索引包含值10,11,13和20 此索引的可能的下一键锁定包括以下间隔, 其中圆括号表示排除间隔终点和a 方括号表示包含端点:
(负无穷大,10]
(10,11)
(11,13)
(13,20)
(20,正无穷大)
但是我发现当你在一个条件下执行更新时会锁定像(11,13)[13,20]这样的东西"其中id = 13"
我的测试
mysql> show create table myorder\G
*************************** 1. row ***************************
Table: myorder
Create Table: CREATE TABLE `myorder` (
`id` int(11) NOT NULL,
`order_id` bigint(20) NOT NULL,
`descr` varchar(45) NOT NULL,
PRIMARY KEY (`id`),
KEY `idx_order_id` (`order_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
表格中的数据
mysql> select * from myorder;
+----+----------+-------+
| id | order_id | descr |
+----+----------+-------+
| 1 | 1 | a |
| 2 | 3 | a |
| 3 | 5 | a |
| 4 | 10 | a |
+----+----------+-------+
4 rows in set (0.00 sec)
会话1执行sql
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> update myorder set descr='b' where order_id=3;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
会话2执行sql
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into myorder values(5, 4, 'a');
并且会话2中的插入挂起
检查锁定信息
mysql> select * from information_schema.innodb_locks\G
*************************** 1. row ***************************
lock_id: 3922:16:4:4
lock_trx_id: 3922
lock_mode: X,GAP
lock_type: RECORD
lock_table: `test`.`myorder`
lock_index: idx_order_id
lock_space: 16
lock_page: 4
lock_rec: 4
lock_data: 5, 3
*************************** 2. row ***************************
lock_id: 3914:16:4:4
lock_trx_id: 3914
lock_mode: X,GAP
lock_type: RECORD
lock_table: `test`.`myorder`
lock_index: idx_order_id
lock_space: 16
lock_page: 4
lock_rec: 4
lock_data: 5, 3
2 rows in set (0.00 sec)
交易信息
---TRANSACTION 3922, ACTIVE 80 sec inserting
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 360, 1 row lock(s), undo log entries 1
MySQL thread id 22, OS thread handle 0x700000ac7000, query id 274 localhost root update
insert into myorder values(5, 4, 'a')
------- TRX HAS BEEN WAITING 2 SEC FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 16 page no 4 n bits 72 index `idx_order_id` of table `test`.`myorder` trx id 3922 lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 4 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 8; hex 8000000000000005; asc ;;
1: len 4; hex 80000003; asc ;;
------------------
---TRANSACTION 3914, ACTIVE 2695 sec
4 lock struct(s), heap size 1184, 3 row lock(s), undo log entries 1
MySQL thread id 21, OS thread handle 0x700000a3f000, query id 270 localhost root cleaning up
且会话1的transId为3914,会话2的transId为3922
根据MySQL的文档,update将设置下一键锁定,而下一键锁定的范围应为(1,3)
所以,我的问题是
由于