簡體   English   中英

間隙鎖沒有出現在 data_locks 表中 - 發生了什么?

[英]gap locks don't appear in data_locks table - What's happening?

Window 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)

Window 2:

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(在 window 2 中)

“id”是主鍵

對於鎖定讀取(SELECT with 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

此外,它們應該出現,因為是唯一索引但范圍搜索,而不是唯一搜索條件

事實上,它們是肉眼不可見的:

Record X = Record lock + gap lock = Next-key lock

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM