MySQL Lock--MySQL INSERT加鎖學習


准備測試數據:

## 開啟InnoDB Monitor
SET GLOBAL innodb_status_output=ON;
SET GLOBAL innodb_status_output_locks=ON;

## 創建測試表
DROP TABLE IF EXISTS tb1001;

CREATE TABLE `tb1001` (
  `order_id` INT(11) NOT NULL,
  `order_num` INT(11) DEFAULT NULL,
  `order_type` INT(11) DEFAULT NULL,
  PRIMARY KEY (`order_id`),
  KEY `idx_order_type` (`order_type`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;

## 准備測試數據
INSERT INTO tb1001(order_id,order_num,order_type)
VALUES(10,10,10),(20,10,20),(21,10,20),(30,10,30),(40,10,40);


## 查看當前表數據
SELECT * FROM tb1001;
+----------+-----------+------------+
| order_id | order_num | order_type |
+----------+-----------+------------+
|       10 |        10 |         10 |
|       20 |        10 |         20 |
|       21 |        10 |         20 |
|       30 |        10 |         30 |
|       40 |        10 |         40 |
+----------+-----------+------------+

 

測試1:

## 先執行事務A但不提交
BEGIN;
INSERT INTO tb1001(order_id,order_num,order_type)
VALUES(19,20,10)

上面操作執行后,使用SHOW ENGINE INNODB STATUS查看鎖信息

---TRANSACTION 1454597, ACTIVE 353 sec
2 lock struct(s), heap size 1136, 1 row lock(s), undo log entries 1
MySQL thread id 83, OS thread handle 140361075443456, query id 293 127.0.0.1 admin
TABLE LOCK table `db001`.`tb1001` trx id 1454597 lock mode IX
RECORD LOCKS space id 29 page no 3 n bits 80 index PRIMARY of table `db001`.`tb1001` trx id 1454597 lock_mode X locks rec but not gap
Record lock, heap no 7 PHYSICAL RECORD: n_fields 5; compact format; info bits 0
 0: len 4; hex 80000013; asc     ;;
 1: len 6; hex 000000163205; asc     2 ;;
 2: len 7; hex a50000001c0110; asc        ;;
 3: len 4; hex 80000014; asc     ;;
 4: len 4; hex 8000000a; asc     ;;

上面事務加兩個鎖:

1、表上加意向修改鎖(IX)。

2、在新插入的記錄上加行鎖(RECORD LOCKS ..lock_mode X locks rec but not gap)

 

測試2:

## 先執行事務A但不提交
BEGIN;
INSERT INTO tb1001(order_id,order_num,order_type)
VALUES(19,20,10)

## 先執行事務B
## 事務B被阻塞
BEGIN;
INSERT INTO tb1001(order_id,order_num,order_type)
VALUES(19,20,10)

上面操作執行后,使用SHOW ENGINE INNODB STATUS查看鎖信息

---TRANSACTION 1454599, ACTIVE 4 sec inserting
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 1136, 1 row lock(s)
MySQL thread id 82, OS thread handle 140361075709696, query id 335 127.0.0.1 admin update
INSERT INTO tb1001(order_id,order_num,order_type)
VALUES(19,20,10)
------- TRX HAS BEEN WAITING 4 SEC FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 29 page no 3 n bits 80 index PRIMARY of table `db001`.`tb1001` trx id 1454599 lock mode S waiting
Record lock, heap no 7 PHYSICAL RECORD: n_fields 5; compact format; info bits 0
 0: len 4; hex 80000013; asc     ;;
 1: len 6; hex 000000163205; asc     2 ;;
 2: len 7; hex a50000001c0110; asc        ;;
 3: len 4; hex 80000014; asc     ;;
 4: len 4; hex 8000000a; asc     ;;

------------------
TABLE LOCK table `db001`.`tb1001` trx id 1454599 lock mode IX
RECORD LOCKS space id 29 page no 3 n bits 80 index PRIMARY of table `db001`.`tb1001` trx id 1454599 lock mode S waiting
Record lock, heap no 7 PHYSICAL RECORD: n_fields 5; compact format; info bits 0
 0: len 4; hex 80000013; asc     ;;
 1: len 6; hex 000000163205; asc     2 ;;
 2: len 7; hex a50000001c0110; asc        ;;
 3: len 4; hex 80000014; asc     ;;
 4: len 4; hex 8000000a; asc     ;;

---TRANSACTION 1454597, ACTIVE 590 sec
2 lock struct(s), heap size 1136, 1 row lock(s), undo log entries 1
MySQL thread id 83, OS thread handle 140361075443456, query id 293 127.0.0.1 admin
TABLE LOCK table `db001`.`tb1001` trx id 1454597 lock mode IX
RECORD LOCKS space id 29 page no 3 n bits 80 index PRIMARY of table `db001`.`tb1001` trx id 1454597 lock_mode X locks rec but not gap
Record lock, heap no 7 PHYSICAL RECORD: n_fields 5; compact format; info bits 0
 0: len 4; hex 80000013; asc     ;;
 1: len 6; hex 000000163205; asc     2 ;;
 2: len 7; hex a50000001c0110; asc        ;;
 3: len 4; hex 80000014; asc     ;;
 4: len 4; hex 8000000a; asc     ;;

查看事務鎖信息:

SELECT * 
FROM `information_schema`.`INNODB_LOCKS` \G
*************************** 1. row *************************** lock_id: 1454606:29:3:7 lock_trx_id: 1454606 lock_mode: S lock_type: RECORD lock_table: `db001`.`tb1001` lock_index: PRIMARY lock_space: 29 lock_page: 3 lock_rec: 7 lock_data: 19
*************************** 2. row *************************** lock_id: 1454605:29:3:7 lock_trx_id: 1454605 lock_mode: X lock_type: RECORD lock_table: `db001`.`tb1001` lock_index: PRIMARY lock_space: 29 lock_page: 3 lock_rec: 7 lock_data: 19

綠色表示鎖申請完成,黃色表示申請鎖失敗被阻塞。

加鎖詳解:

Insert操作加鎖規則
1、INSERT操作會對新插入的記錄加行鎖(ROW LOCK)+排他鎖(X LOCK),不會產生任何GAP鎖和Next-Key鎖
2、在插入記錄前,會向插入記錄所在位置申請意向插入Gap鎖(Insertion Intention Gap LOCK),相同區間的意向插入Gap鎖不會沖突。
3、對於唯一索引,如果插入記錄時表中已存在相同鍵值記錄(被其他事務修改且未提交),即存在唯一鍵沖突,會嘗試在已有記錄上加讀鎖,然后等待。

加鎖操作:
1、事務A插入操作完成,對新插入記錄加行鎖(ROW LOCK)+排他鎖(X LOCK),且不會任何加GAP鎖,因此鎖信息為:
	RECORD LOCKS SPACE id 29 page NO 3 n bits 80 INDEX PRIMARY of TABLE `db001`.`tb1001` trx id 1454605 lock_mode X LOCKS rec but NOT gap
	Record LOCK, HEAP NO 7 PHYSICAL RECORD: n_fields 5; COMPACT FORMAT; info bits 0
	0: len 4; HEX 80000013; ASC     ;;  order_id=19
	
2、事務B執行插入操作,由於在記錄order_id=19上存在唯一鍵沖突,因此改為申請記錄order_id=19上的S鎖,又由於事務A上持有記錄order_id=19上的行鎖(ROW LOCK)+排他鎖(X LOCK),事務B申請S鎖被阻塞,鎖信息為:
	RECORD LOCKS SPACE id 29 page NO 3 n bits 80 INDEX PRIMARY of TABLE `db001`.`tb1001` trx id 1454606 LOCK MODE S waiting
	Record LOCK, HEAP NO 7 PHYSICAL RECORD: n_fields 5; COMPACT FORMAT; info bits 0
	0: len 4; HEX 80000013; ASC     ;; order_id=19

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM