什么是mysql中更新创建的下一行密钥的范围

时间:2016-09-08 13:39:33

标签: mysql innodb

要找到下一行键锁的范围,我做了一些测试。我发现它与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)

所以,我的问题是

  1. 为什么会话2在尝试插入数据时会挂断" order_id = 4",似乎(1,3)[3,5]都被锁定
  2. 根据交易信息,会话2(3922)正在等待" lock_mode X在重新插入意图等待"之前锁定间隙,这意味着它需要锁定" insert-intention-lock&# 34 ;?根据该文件,"这里也值得注意的是,冲突的锁可以通过不同的交易保持在一个间隙上。 ",这意味着插入意图锁定应立即授予会话2?
  3. 由于

0 个答案:

没有答案