本篇文章带大家聊聊MySQL,介绍一下InnoDB中锁的情况。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。
mysql> select @@version; +-----------+ | @@version | +-----------+ | 5.7.21 | +-----------+ 1 row in set (0.01 sec)
一,锁的基本介绍
相对其他数据库而言,MySQL的锁机制比较简单,其最显著的特点是不同的存储引擎支持不同的锁机制。比如,MyISAM和MEMORY存储引擎采用的是表级锁(table-level locking);InnoDB存储引擎既支持行级锁(row-level locking),也支持表级锁,但默认情况下是采用行级锁。
表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。
行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
行级锁类型:
Record Lock(记录锁):当个记录的锁(锁住单条记录)
记录锁只会锁住索引的记录,如果InnoDB存储表在建立的时候没有任何索引,那么这个锁会使用隐式的主键来进行锁定,如下图
Gap Lock(间隙锁):锁定一个范围,不包括记录本身(只锁数据前面的GAP)
如下图为的锁就是GAP锁,就是不允许其他事务在索引列8之前的间隙插入新的记录,也就是(3 , 8)这个区间。gap锁 的作用仅仅是为了防止插入幻影记录的而已
Next-Key Lock(临键锁):同时锁住记录和记录前面的GAP,也就是Next-Key Lock = Record Lock + Gap Lock。
二,锁的分类
共享锁 Share Locks (简称S锁,属于行锁)
排它锁 Exclusive Locks (简称X锁,属于行锁)
意向共享锁 Intention Share Locks (简称IS锁,属于表锁)
意向排它锁 Intention Exclusive Locks (简称IX锁,属于表锁)
自增锁 AUTO-INC Locks(属于表锁)
下面具体介绍下每种类型的锁,我们先建一张innodb的表,sql如下
create table tab_with_index(id int,name varchar(10)) engine=innodb; alter table tab_with_index add index id(id); insert into tab_with_index values(1,'1'),(2,'2'),(3,'3'),(4,'4');
共享锁
共享锁就是多个事务对于同一个数据可以共享一把锁,都能访问数据库,但是只能读不能修改;
事务A:
select * from tab_with_index lock in share mode;
事务B:
select * from tab_with_index where id =1; // 可以查询数据
update tab_with_index set name = 'aa' where id = 1 ;
注意:这里的修改语句会堵塞住,直到事务A提交之后才能操作成功。
排它锁
排它锁不能与其他锁并存,如一个事务获取了一个数据行的排它锁,其他事务就不能在获取该行的锁,只有当前获取排它锁的事务可以对数据进行修改。(delete,update,create默认是排它锁)
事务A:
select * from tab_with_index where id =1 for update;
事务B:
select * from tab_with_index where id =1; //可以获取结果
select * from tab_with_index where id =1 for update; // 堵塞
select * from tab_with_index where id = 1 lock for share mode; // 堵塞
注意:事务B两个sql都会堵塞住,也就是获取不到共享锁也获取不到排它锁,直到事务A提交之后才能操作成功。
意向共享锁和意向排它锁
意向共享锁:表示事务准备给数据行加入共享锁,也就是说一个数据行在加共享锁之前必须先获取该表的IS锁。
意向排它锁:表示事务准备给数据行加入排它锁,也就是说一个数据行加排它锁之前必须先获取该表的IX锁。
IS锁和IX锁是表级锁,他们的提出仅仅为了在之后加表级别的S锁和X锁时可以快速判断表中的记录是否被上锁,以避免用遍历的方式来查看表中有没有上锁的记录,也就是说其实IS锁和IX锁是兼容的,IX锁和IX锁是兼容的。 《MySQL是怎样运行的》
自增锁
针对自增列自增长的一个特殊的表级别锁。
show variables like 'innodb_autoinc_lock_mode'; -- 默认值1,代表连续,事务未提交则ID永久丢失
三,InnoDB锁
1、事务及其ACID属性
事务是由一组SQL语句组成的逻辑处理单元,事务具有4属性,通常称为事务的ACID属性。
原子性(Actomicity):事务是一个原子操作单元,其对数据的修改,要么全都执行,要么全都不执行。 一致性(Consistent):在事务开始和完成时,数据都必须保持一致状态。 隔离性(Isolation):数据库系统提供一定的隔离机制,保证事务在不受外部并发操作影响的“独立”环境执行。 持久性(Durable):事务完成之后,它对于数据的修改是永久性的,即使出现系统故障也能够保持。
2、并发事务带来的问题
相对于串行处理来说,并发事务处理能大大增加数据库资源的利用率,提高数据库系统的事务吞吐量,从而可以支持