一、Mysql锁概述
1、锁的分类
Mysql中锁分为3类:页级锁、表级锁、行级锁。
页级锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。会发生在:BDB存储引擎。
表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。会发生在:MyISAM、memory、InnoDB、BDB等存储引擎中。
行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。会发生在:InnoDB存储引擎。
存储引擎 | 页级锁 | 表级锁 | 行级锁 |
---|---|---|---|
BDB | √ | √ | |
MyISAM | √ | ||
InnoDB | √ | √ |
2、表级锁
表级锁有2种类型:表共享读锁(Table Read Lock)和表独占写锁(Table Write Lock)。
锁模式的兼容性:
- 对MyISAM表的读操作,不会阻塞其他用户对同一表的读请求,但会阻塞对同一表的写操作;
- 对MyISAM表的写操作,则会阻塞其他用户对同一表的读和写操作;
3、行级锁
行级锁包含2种:共享锁(S)和排他锁(X)。
- 共享锁(s):又称读锁。允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁
- 排他锁(X):又称写锁。允许获取排他锁的事务更新数据,阻止其他事务取得相同的数据集共享读锁和排他写锁。
二、InnoDB中的锁
InnoDB中使用的锁有表锁和行锁。
1、表锁
1)意向锁
为了允许行锁和表锁共存,实现多粒度锁机制,InnoDB还有两种内部使用的意向锁(Intention Locks),这两种意向锁都是表锁。在加行锁之前必须先获得表级意向锁,否则等待innodb_lock_wait_timeout超时后根据innodb_rollback_on_timeout决定是否回滚事务。
- 意向共享锁(IS):事务打算给数据行加行共享锁,事务在给一个数据行加共享锁前必须先取得该表的IS锁。
- 意向排他锁(IX):事务打算给数据行加行排他锁,事务在给一个数据行加排他锁前必须先取得该表的IX锁。
InnoDB行锁模式兼容性如下表:
X | IX | S | IS | |
---|---|---|---|---|
X | ||||
IX | √ | √ | ||
S | √ | √ | ||
IS | √ | √ | √ |
2)自增锁
在MySQL InnoDB存储引擎中,我们在设计表结构的时候,通常会建议添加一列作为自增主键。这里就会涉及到一个特殊的锁:自增锁(即:AUTO-INC lock),它属于表锁的一种,在insert结束后立即释放。我们可以执行show engine innodb status\G
来查看自增锁的状态信息。
2、行锁
InnoDB行锁是通过对索引数据页上的记录(record)加锁实现。所以,只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁。
主要实现算法有3种:
- record lock锁:单个行记录的锁(锁数据,不锁Gap)
- gap lock锁:间隙锁,锁定一个范围,不包括记录本身(不锁数据,仅仅锁数据前面的Gap)
- next-key lock锁:同时锁住数据,并且锁住数据前面的Gap。所以:next-key lock = record lock + gap lock
3、InnoDB死锁以及处理
InnoDB是逐行加锁,极容易产生死锁。
1)产生死锁的四个条件
- 互斥条件:一个资源每次只能被一个进程使用;
- 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放;
- 不剥夺条件:进程已获得的资源,在没使用完之前,不能强行剥夺;
- 循环等待条件:多个进程之间形成一种互相循环等待资源的关系。
在发生死锁时,InnoDB存储引擎会自动检测,并且会自动回滚代价较小的事务来解决死锁。但很多时候一旦死锁发生,InnoDB存储引擎的处理的效率是很低下的或者有时候根本解决不了,需要人为手动去解决。
2)锁问题排查
排查InnoDB锁问题通常可以有2种方法:
- 第一种:打开innodb_lock_monitor表,注意使用后记得关闭,会影响性能。
- 第二种:在MySQL5.5之后,可以通过查看information_schema库下面的innodb_locks,innodb_lock_waits,innodb_trx 三个视图
3)避免死锁的办法
- 加锁顺序一致
- 尽量基于primary或unique key更新数据
- 单次操作数据量不宜过多,涉及表尽量少
- 减少表上索引,减少锁定资源
- 相关工具:pt-deadlock-logger
参考文献
1、https://zhuanlan.zhihu.com/p/76390004
2、https://www.cnblogs.com/leedaily/p/8378779.html
3、https://blog.csdn.net/zcl_love_wx/article/details/81977447
4、https://blog.csdn.net/zcl_love_wx/article/details/81983267