MySQL版本:8.0.29
测试表:
测试数据:
开始测试:
事务1执行
加锁分析:
mysql> SELECT * FROM performance_schema.data_locks\G
*************************** 1. row ***************************
ENGINE: INNODB
ENGINE_LOCK_ID: 140346328945336:1068:140346432671984
ENGINE_TRANSACTION_ID: 4017
THREAD_ID: 81
EVENT_ID: 17
OBJECT_SCHEMA: db_study
OBJECT_NAME: staff
PARTITION_NAME: NULL
SUBPARTITION_NAME: NULL
INDEX_NAME: NULL
OBJECT_INSTANCE_BEGIN: 140346432671984
LOCK_TYPE: TABLE
LOCK_MODE: IX
LOCK_STATUS: GRANTED
LOCK_DATA: NULL
1 row in set (0.00 sec)
事务1 insert操作相当于不加锁(会加page x latch)
事务2执行
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into staff(staff_no,name) values(7,'qgl');
阻塞在这里
加锁分析:
mysql> SELECT * FROM performance_schema.data_locks\G
*************************** 1. row ***************************
ENGINE: INNODB
ENGINE_LOCK_ID: 140346328944544:1068:140346432670032
ENGINE_TRANSACTION_ID: 4018
THREAD_ID: 80
EVENT_ID: 36
OBJECT_SCHEMA: db_study
OBJECT_NAME: staff
PARTITION_NAME: NULL
SUBPARTITION_NAME: NULL
INDEX_NAME: NULL
OBJECT_INSTANCE_BEGIN: 140346432670032
LOCK_TYPE: TABLE
LOCK_MODE: IX
LOCK_STATUS: GRANTED
LOCK_DATA: NULL
*************************** 2. row ***************************
ENGINE: INNODB
ENGINE_LOCK_ID: 140346328944544:7:5:5:140346462116384
ENGINE_TRANSACTION_ID: 4018
THREAD_ID: 80
EVENT_ID: 36
OBJECT_SCHEMA: db_study
OBJECT_NAME: staff
PARTITION_NAME: NULL
SUBPARTITION_NAME: NULL
INDEX_NAME: idx_staff_no
OBJECT_INSTANCE_BEGIN: 140346462116384
LOCK_TYPE: RECORD
LOCK_MODE: S
LOCK_STATUS: WAITING
LOCK_DATA: 7, 6
*************************** 3. row ***************************
ENGINE: INNODB
ENGINE_LOCK_ID: 140346328945336:1068:140346432671984
ENGINE_TRANSACTION_ID: 4017
THREAD_ID: 81
EVENT_ID: 17
OBJECT_SCHEMA: db_study
OBJECT_NAME: staff
PARTITION_NAME: NULL
SUBPARTITION_NAME: NULL
INDEX_NAME: NULL
OBJECT_INSTANCE_BEGIN: 140346432671984
LOCK_TYPE: TABLE
LOCK_MODE: IX
LOCK_STATUS: GRANTED
LOCK_DATA: NULL
*************************** 4. row ***************************
ENGINE: INNODB
ENGINE_LOCK_ID: 140346328945336:7:5:5:140346462120992
ENGINE_TRANSACTION_ID: 4017
THREAD_ID: 80
EVENT_ID: 36
OBJECT_SCHEMA: db_study
OBJECT_NAME: staff
PARTITION_NAME: NULL
SUBPARTITION_NAME: NULL
INDEX_NAME: idx_staff_no
OBJECT_INSTANCE_BEGIN: 140346462120992
LOCK_TYPE: RECORD
LOCK_MODE: X,REC_NOT_GAP
LOCK_STATUS: GRANTED
LOCK_DATA: 7, 6
4 rows in set (0.00 sec)
事务1的id是4017,可以看到相比之前多了(7,6)行排他锁。
事务2的id是4018,加了(5,7]的next-key S锁。
事务1执行:
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into staff(staff_no,name) values(7,'hcy');
Query OK, 1 row affected (0.00 sec)
加锁分析:
mysql> SELECT * FROM performance_schema.data_locks\G
*************************** 1. row ***************************
ENGINE: INNODB
ENGINE_LOCK_ID: 140346328945336:1068:140346432671984
ENGINE_TRANSACTION_ID: 4019
THREAD_ID: 81
EVENT_ID: 21
OBJECT_SCHEMA: db_study
OBJECT_NAME: staff
PARTITION_NAME: NULL
SUBPARTITION_NAME: NULL
INDEX_NAME: NULL
OBJECT_INSTANCE_BEGIN: 140346432671984
LOCK_TYPE: TABLE
LOCK_MODE: IX
LOCK_STATUS: GRANTED
LOCK_DATA: NULL
1 row in set (0.01 sec)
事务1不加锁
事务2执行:
mysql> SELECT * FROM performance_schema.data_locks\G
*************************** 1. row ***************************
ENGINE: INNODB
ENGINE_LOCK_ID: 140346328944544:1068:140346432670032
ENGINE_TRANSACTION_ID: 4024
THREAD_ID: 80
EVENT_ID: 40
OBJECT_SCHEMA: db_study
OBJECT_NAME: staff
PARTITION_NAME: NULL
SUBPARTITION_NAME: NULL
INDEX_NAME: NULL
OBJECT_INSTANCE_BEGIN: 140346432670032
LOCK_TYPE: TABLE
LOCK_MODE: IX
LOCK_STATUS: GRANTED
LOCK_DATA: NULL
*************************** 2. row ***************************
ENGINE: INNODB
ENGINE_LOCK_ID: 140346328944544:7:5:5:140346462116384
ENGINE_TRANSACTION_ID: 4024
THREAD_ID: 80
EVENT_ID: 40
OBJECT_SCHEMA: db_study
OBJECT_NAME: staff
PARTITION_NAME: NULL
SUBPARTITION_NAME: NULL
INDEX_NAME: idx_staff_no
OBJECT_INSTANCE_BEGIN: 140346462116384
LOCK_TYPE: RECORD
LOCK_MODE: X
LOCK_STATUS: WAITING
LOCK_DATA: 7, 8
*************************** 3. row ***************************
ENGINE: INNODB
ENGINE_LOCK_ID: 140346328945336:1068:140346432671984
ENGINE_TRANSACTION_ID: 4019
THREAD_ID: 81
EVENT_ID: 21
OBJECT_SCHEMA: db_study
OBJECT_NAME: staff
PARTITION_NAME: NULL
SUBPARTITION_NAME: NULL
INDEX_NAME: NULL
OBJECT_INSTANCE_BEGIN: 140346432671984
LOCK_TYPE: TABLE
LOCK_MODE: IX
LOCK_STATUS: GRANTED
LOCK_DATA: NULL
*************************** 4. row ***************************
ENGINE: INNODB
ENGINE_LOCK_ID: 140346328945336:7:5:5:140346462120992
ENGINE_TRANSACTION_ID: 4019
THREAD_ID: 80
EVENT_ID: 40
OBJECT_SCHEMA: db_study
OBJECT_NAME: staff
PARTITION_NAME: NULL
SUBPARTITION_NAME: NULL
INDEX_NAME: idx_staff_no
OBJECT_INSTANCE_BEGIN: 140346462120992
LOCK_TYPE: RECORD
LOCK_MODE: X,REC_NOT_GAP
LOCK_STATUS: GRANTED
LOCK_DATA: 7, 8
4 rows in set (0.00 sec)
事务1的id是4019,同样也是加了行排他锁(7,8)
事务2的id是4024,相比普通的insert操作,这次加的是(5,7]next-key X锁
疑问:
MySQL,insert时唯一索引冲突,为什么会加next-key锁?