InnoDB存储引擎中的锁
锁的类型
InnoDB存储引擎实现了如下两种标准的行级锁
- 共享锁(S Lock),允许事务读一行数据。
- 排他锁(X Lock),允许事务删除或者更新一行数据。
InnoDB存储引擎支持多粒度锁定,这种锁定允许在行级上的锁和表级上的锁同时存在。
为了支持在不同粒度上进行加锁操作,InnoDB存储引擎支持一种额外的锁方式,我们称之为意向锁
。
意向锁是表级别的锁,InnoDB存储引擎支持两种意向锁
- 意向共享锁(IS Lock),事务想要获得一个表中某几行的共享锁。
- 意向排他锁(IX Lock),事务想要获得一个表中某几行的排他锁。
锁的算法
InnoDB存储引擎有3种行锁的算法设计
- Record Lock:单个行记录上的锁
Record Lock总是会去锁住索引记录。如果InnoDB存储引擎表建立的时候没有设置任何一个索引,
这时InnoDB存储引擎会使用隐式的主键来进行锁定 - Gap Lock:间隙锁,锁定一个范围,但不包含记录本身
- Next-Key Lock:Gap Lock + Record Lock,锁定一个范围,并且锁定记录本身
会话1
rollback; start transaction; select * from t where id=5 lock in share mode;
会话2
rollback; start transaction; insert into t values(6);
mysql> show engine innodb status;
..
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 1136, 1 row lock(s), undo log entries 1
MySQL thread id 16, OS thread handle 123145426382848, query id 763 localhost 127.0.0.1 root update
insert into t values(6)
------- TRX HAS BEEN WAITING 6 SEC FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 2496 page no 4 n bits 80 index idx_t of table `promotion`.`t` trx id 9588882 lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 6 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 4; hex 80000007; asc ;;
1: len 6; hex 0000010a1804; asc ;;
------------------
mysql> select * from information_schema.INNODB_LOCKS\G; *************************** 1. row *************************** lock_id: 9588880:2496:4:6 lock_trx_id: 9588880 lock_mode: X,GAP lock_type: RECORD lock_table: `promotion`.`t` lock_index: idx_t lock_space: 2496 lock_page: 4 lock_rec: 6 lock_data: 7 *************************** 2. row *************************** lock_id: 281479500060464:2496:4:6 lock_trx_id: 281479500060464 lock_mode: S,GAP lock_type: RECORD lock_table: `promotion`.`t` lock_index: idx_t lock_space: 2496 lock_page: 4 lock_rec: 6 lock_data: 7 2 rows in set (0.01 sec)