mysql 间隙锁未出现在data_locks表中-发生了什么?

xxe27gdn  于 2023-01-08  发布在  Mysql
关注(0)|答案(1)|浏览(166)

窗口1:

mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from table1 where id > 99 FOR UPDATE;
+-----+--------+--------+-------+------+
| id  | field1 | field2 | field | a    |
+-----+--------+--------+-------+------+
| 101 | hola   | NULL   | NULL  | NULL |
| 103 | yo     | NULL   | NULL  | NULL |
| 107 | hey    | NULL   | NULL  | NULL |
+-----+--------+--------+-------+------+
3 rows in set (0.00 sec)

窗口二:

mysql> SELECT thread_id, event_id,
    -> object_schema, object_name, index_name,
    -> lock_type, lock_mode, lock_status, lock_data
    -> FROM performance_schema.data_locks
    -> WHERE thread_id = 279\G;
*************************** 1. row ***************************
    thread_id: 279
     event_id: 28
object_schema: laravel_doc
  object_name: table1
   index_name: NULL
    lock_type: TABLE
    lock_mode: IX
  lock_status: GRANTED
    lock_data: NULL
*************************** 2. row ***************************
    thread_id: 279
     event_id: 28
object_schema: laravel_doc
  object_name: table1
   index_name: PRIMARY
    lock_type: RECORD
    lock_mode: X
  lock_status: GRANTED
    lock_data: supremum pseudo-record
*************************** 3. row ***************************
    thread_id: 279
     event_id: 28
object_schema: laravel_doc
  object_name: table1
   index_name: PRIMARY
    lock_type: RECORD
    lock_mode: X
  lock_status: GRANTED
    lock_data: 101
*************************** 4. row ***************************
    thread_id: 279
     event_id: 28
object_schema: laravel_doc
  object_name: table1
   index_name: PRIMARY
    lock_type: RECORD
    lock_mode: X
  lock_status: GRANTED
    lock_data: 103
*************************** 5. row ***************************
    thread_id: 279
     event_id: 28
object_schema: laravel_doc
  object_name: table1
   index_name: PRIMARY
    lock_type: RECORD
    lock_mode: X
  lock_status: GRANTED
    lock_data: 107
5 rows in set (0.00 sec)

原始表格:

+-----+--------+--------+-------+------+
| id  | field1 | field2 | field | a    |
+-----+--------+--------+-------+------+
|   3 | hello  | 1      | NULL  | NULL |
|  97 | hi     | 2      | NULL  | NULL |
| 101 | hola   | 3      | NULL  | NULL |
| 103 | yo     | 4      | NULL  | NULL |
| 107 | hey    | 5      | NULL  | NULL |
+-----+--------+--------+-------+------+

间隙锁不显示,它们应该显示,因为我检查了,它阻止我插入,例如id = 102(在窗口2中)

“id”是主键
对于锁定读取(SELECT与FOR UPDATE或FOR SHARE)、UPDATE和DELETE语句,所采用的锁取决于语句使用的是具有唯一搜索条件的唯一索引还是范围类型搜索条件。
对于具有唯一搜索条件的唯一索引,InnoDB只锁定找到的索引记录,而不锁定它之前差距。
对于其他搜索条件和非唯一索引,InnoDB会锁定扫描的索引范围,使用间隙锁或下一个键锁阻止其他会话向该范围覆盖的间隙中插入内容。有关间隙锁和下一个键锁的信息,请参见第15.7.1节“InnoDB锁定”。
https://dev.mysql.com/doc/refman/8.0/en/innodb-locks-set.html

此外,它们应该出现,因为是唯一索引,而不是范围搜索,而不是唯一搜索条件

tyg4sfes

tyg4sfes1#

事实上它们是,只是肉眼看不见:

记录X =记录锁定+间隔锁定=下一个键锁定

https://dev.mysql.com/blog-archive/innodb-data-locking-part-2-locks/
S →就像S,REC_NOT_GAP和S,GAP同时组合在一起,所以它是对行的共享访问权限,并防止在它之前插入。
X →就像是X,REC_NOT_GAP和X,GAP同时组合在一起,所以它是对该行的独占访问权限,并防止在该行之前插入。
https://xhinliang.win/2021/09/backend/innodb-locks/
LOCK_MODE有几个选项

IX -> Intention Exclusive Lock
IS -> Intention Share Lock
X,REC_NOT_GAP -> Exclusive Record Lock
X,GAP -> Exclusive Gap Lock
X -> Exclusive Next-Key Lock
S,REC_NOT_GAP -> Share Record Lock
S,GAP -> Share Gap Lock
S -> Share Next-Key Lock

相关问题