聊到mysql的锁,好像就有了一个聊不完的话题。网上一搜感觉各种答案都有,各种方式的描述也有,种类繁多,描述繁琐,反正看来看去,基本最后看多少忘记多少。
mysql 分储存引擎来聊锁。myisam 表锁,innodb行锁、表锁。
行锁:
共享锁(S锁:share):当读取一行记录的时候,为了防止其他人修改,则需要加S锁。
排它锁(X锁:exclusive):当修改一行的记录的时候,为了防止其他人同时修改,则需要添加X锁。
X | S | |
---|---|---|
X | 不兼容 | 不兼容 |
S | 不兼容 | 兼容 |
记录锁:添加在行索引上的锁
间隙锁:锁定范围是索引记录之间的间隙,针对可重复读以上隔离级别
临键锁:记录锁+间隙锁
表锁:
意向锁:在获取某行的锁之前,必须要获取表的锁,分为意向共享锁,意向排它锁
自增锁:对自增字段所采用的特殊表级锁
锁模式的含义:
IX:意向排它锁,表示是将要在表上加排他锁。
X:锁定记录本身和记录之前的间隙
S:锁定记录本身和记录之前的间隙
X,REC_NOT_GAP:只锁定记录本身
S,REC_NOT_GAP:只锁定记录本身
X,GAP:间隙锁,不锁定记录本身
S,GAP:间隙锁,不锁定记录本身
X,GAP,INSERT_INTENTION:插入意向锁
锁一般在什么情况下会出现?
不同的引擎出现不同的锁,MyIasm 只有表锁,Innodb 就表锁 行锁都会有。一般锁的出现会在使用事务的时候为了保证当前事务的一致性,用到了 for update语句,或者update xxx where xxx 、等语句的时候出现。
我们如何查看到这些锁?
首先设置开启锁信息输出:
然后:
begin;
select * from t for update;
show engine innodb status\G;
执行结果如下:
Query OK, 0 rows affected (0.00 sec)
+------+------+
| id | name |
+------+------+
| 10 | 10 |
| 20 | 20 |
| 30 | 30 |
+------+------+
3 rows in set (0.00 sec)
*************************** 1. row ***************************
Type: InnoDB
Name:
Status:
=====================================
2021-05-08 09:58:23 0x7fde205d2700 INNODB MONITOR OUTPUT
=====================================
Per second averages calculated from the last 13 seconds
-----------------
BACKGROUND THREAD
-----------------
srv_master_thread loops: 5 srv_active, 0 srv_shutdown, 2447 srv_idle
srv_master_thread log flush and writes: 0
----------
SEMAPHORES
----------
OS WAIT ARRAY INFO: reservation count 6
OS WAIT ARRAY INFO: signal count 5
RW-