在会话 1 执行 START TRANSACTION; insert into t1 values (5,'a'); 之后,select * from performance_schema.data_locks; 的输出是:
+--------+--------------------------------------+-----------------------+-----------+----------+---------------+-------------+----------------+-------------------+------------+-----------------------+-----------+-----------+-------------+-----------+
| ENGINE | ENGINE_LOCK_ID | ENGINE_TRANSACTION_ID | THREAD_ID | EVENT_ID | OBJECT_SCHEMA | OBJECT_NAME | PARTITION_NAME | SUBPARTITION_NAME | INDEX_NAME | OBJECT_INSTANCE_BEGIN | LOCK_TYPE | LOCK_MODE | LOCK_STATUS | LOCK_DATA |
+--------+--------------------------------------+-----------------------+-----------+----------+---------------+-------------+----------------+-------------------+------------+-----------------------+-----------+-----------+-------------+-----------+
| INNODB | 139675093921992:1063:139675020906192 | 2117 | 52 | 31 | test | t1 | NULL | NULL | NULL | 139675020906192 | TABLE | IX | GRANTED | NULL |
+--------+--------------------------------------+-----------------------+-----------+----------+---------------+-------------+----------------+-------------------+------------+-----------------------+-----------+-----------+-------------+-----------+
在会话 2 执行 update t1 set name='a2' where id > 4 and id < 5; 之后,输出为:
+--------+---------------------------------------+-----------------------+-----------+----------+---------------+-------------+----------------+-------------------+------------+-----------------------+-----------+---------------+-------------+----------------------------+
| ENGINE | ENGINE_LOCK_ID | ENGINE_TRANSACTION_ID | THREAD_ID | EVENT_ID | OBJECT_SCHEMA | OBJECT_NAME | PARTITION_NAME | SUBPARTITION_NAME | INDEX_NAME | OBJECT_INSTANCE_BEGIN | LOCK_TYPE | LOCK_MODE | LOCK_STATUS | LOCK_DATA |
+--------+---------------------------------------+-----------------------+-----------+----------+---------------+-------------+----------------+-------------------+------------+-----------------------+-----------+---------------+-------------+----------------------------+
| INNODB | 139675093921144:1063:139675020900048 | 2118 | 49 | 29 | test | t1 | NULL | NULL | NULL | 139675020900048 | TABLE | IX | GRANTED | NULL |
| INNODB | 139675093921144:2:5:6:139675020897056 | 2118 | 49 | 29 | test | t1 | NULL | NULL | idx_id | 139675020897056 | RECORD | X | WAITING | 0x0000A040, 0x000000000208 |
| INNODB | 139675093921992:1063:139675020906192 | 2117 | 52 | 31 | test | t1 | NULL | NULL | NULL | 139675020906192 | TABLE | IX | GRANTED | NULL |
| INNODB | 139675093921992:2:5:6:139675020903280 | 2117 | 49 | 29 | test | t1 | NULL | NULL | idx_id | 139675020903280 | RECORD | X,REC_NOT_GAP | GRANTED | 0x0000A040, 0x000000000208 |
+--------+---------------------------------------+-----------------------+-----------+----------+---------------+-------------+----------------+-------------------+------------+-----------------------+-----------+---------------+-------------+----------------------------+
会话3执行update t1 set name='a2' where id > 5 and id < 10;后,输出为:
+--------+---------------------------------------+-----------------------+-----------+----------+---------------+-------------+----------------+-------------------+-----------------+-----------------------+-----------+---------------+-------------+----------------------------+
| ENGINE | ENGINE_LOCK_ID | ENGINE_TRANSACTION_ID | THREAD_ID | EVENT_ID | OBJECT_SCHEMA | OBJECT_NAME | PARTITION_NAME | SUBPARTITION_NAME | INDEX_NAME | OBJECT_INSTANCE_BEGIN | LOCK_TYPE | LOCK_MODE | LOCK_STATUS | LOCK_DATA |
+--------+---------------------------------------+-----------------------+-----------+----------+---------------+-------------+----------------+-------------------+-----------------+-----------------------+-----------+---------------+-------------+----------------------------+
| INNODB | 139675093922840:1063:139675020912224 | 2119 | 50 | 30 | test | t1 | NULL | NULL | NULL | 139675020912224 | TABLE | IX | GRANTED | NULL |
| INNODB | 139675093922840:2:5:5:139675020909312 | 2119 | 50 | 30 | test | t1 | NULL | NULL | idx_id | 139675020909312 | RECORD | X | GRANTED | 0x00002041, 0x000000000203 |
| INNODB | 139675093922840:2:4:5:139675020909656 | 2119 | 50 | 30 | test | t1 | NULL | NULL | GEN_CLUST_INDEX | 139675020909656 | RECORD | X,REC_NOT_GAP | GRANTED | 0x000000000203 |
| INNODB | 139675093921144:1063:139675020900048 | 2118 | 49 | 29 | test | t1 | NULL | NULL | NULL | 139675020900048 | TABLE | IX | GRANTED | NULL |
| INNODB | 139675093921144:2:5:6:139675020897056 | 2118 | 49 | 29 | test | t1 | NULL | NULL | idx_id | 139675020897056 | RECORD | X | WAITING | 0x0000A040, 0x000000000208 |
| INNODB | 139675093921992:1063:139675020906192 | 2117 | 52 | 31 | test | t1 | NULL | NULL | NULL | 139675020906192 | TABLE | IX | GRANTED | NULL |
| INNODB | 139675093921992:2:5:6:139675020903280 | 2117 | 49 | 29 | test | t1 | NULL | NULL | idx_id | 139675020903280 | RECORD | X,REC_NOT_GAP | GRANTED | 0x0000A040, 0x000000000208 |
+--------+---------------------------------------+-----------------------+-----------+----------+---------------+-------------+----------------+-------------------+-----------------+-----------------------+-----------+---------------+-------------+----------------------------+
所以,会话 2 被阻止的原因是:它请求 next-key lock (4, 5],即 (4, 5) gap lock 加上 5 index-record lock,但会话 1 持有 5 index-record lock。而会话3没有被阻塞的原因是:它请求next-key lock (5, 10]是(5, 10) gap lock加上10 index-record lock,没有人持有10 index-record lock。