Mysql的锁机制是除了Mysql的MVCC机制外,解决并发过程的幻读等问题的另外的方案,当然性能比mvcc机制较低,因为不允许读写操作并列执行,但是一些特殊机制,必须使用Mysql的锁方案

锁的分类以及CRUD操作下,锁的操作

锁分为S锁和X锁,S锁不会阻塞其他事务请求S锁,而X锁将阻塞其他事务的请求

锁定读

#添加S锁,S锁不会阻塞S锁的请求
begin;
select *from computer lock in share mode;
#添加X锁
begin;
select *from computer limit 5 for update \G;
#获取锁,失败则跳过
begin
select *from s2 limit 5 for update skip locked;
begin
select *from s2 limit 5 for update nowait;

写操作

delete

先进行定位数据位置,获取X锁,获取成功后,进行数据的delete mark操作,记录下删除的数据

insert

插入新的记录,会对新插入的数据加一个隐式锁,防止被其他记录访问到

update

修改了键值时候,会先对记录删除后再插入

未修改键值时:若存储空间未变化,先定位后,用获取X锁,进行修改操作

变化之后,获取记录的X锁,再插入新的数据

锁的粒度

从锁的粒度来看,锁的粒度大小分为行锁和表锁,页锁,表锁不会导致死锁,而行锁可能导致死锁,且inndb引擎支持行锁,而Myisam不支持行锁,只支持表锁(一个事务将锁定整张表,并发能力低)。

1 表级别的锁

inndb锁的锁表语句

1全阻塞的锁表语法

#锁表语句,不建议使用,加s锁
lock tables userbea read;
#锁定写,加X锁
lock tables userbea write;

2 意向锁

inndb支持多粒度级别的锁,支持表级别和行级别锁,而意向锁就是表锁,特点是不会阻塞其他事务的不同数据行

#意向共享锁(intention shared lock, IS):事务有意向对表中的某些行加共享锁(S锁)
select *from computer lock in share mode;
#意向排他锁(intention exclusive lock, IX):事务有意向对表中的某些行加排他锁(X锁)
select *from computer limit 5 for update;

3 自增锁

4 元数据锁(MDL)

MySQL5.5引入了meta data lock,简称MDL锁,属于表锁范畴。MDL 的作用是,保证读写的正确性。比如,如果一个查询正在遍历一个表中的数据,而执行期间另一个线程对这个表结构做变更,增加了一列,那么查询线程拿到的结果跟表结构对不上,肯定是不行的。因此,当对一个表做增删改查操作的时候,加 MDL读锁;当要对表做结构变更操作的时候,加 MDL 写锁

#查看是否有表被锁定
show open tables where in_use>0;
#释放表
unlock tables;

Mysql的锁机制_mysql

Mysql的锁机制_mysql_02

Mysql的锁机制_mysql_03

 锁的总结

Mysql的锁机制_死锁_04

行锁

行锁是针对数据行级别的锁,只有inndb支持行锁,并发能力高,冲突发生低,加锁慢

记录锁(record locks)

记录锁也分为X锁和S锁,从定义上看,与表锁的X锁和S锁是相同的,只是针对行级别进行处理

间隙锁(gaps locks)

是在一条记录的前加入间隙锁(插入于不存在的间隙),使新的数据无法插入这两条记录之间,仅仅防止幻影的产生(注意,如果间隙锁锁住了最大的记录x之外的记录可能产生到无穷区间的间隙锁)

临键锁(Next-key locks)

记录锁和间隙锁的结合体,既能锁住该条记录又能锁住前面的记录

插入意向锁(Insert Intention locks)

插入意向锁会生成类似gap锁的结构,但不会阻止其他事务获取数据

页锁

介于表锁和行锁之间,并发度一般

锁的态度区分

悲观锁

阻塞其他线程获取数据,适用于多写的应用

乐观锁

不阻塞其他线程,使用版本号和时间戳机制来判断更新前后是否有其他数据更新数据(使用CAS机制),适用于多读的应用

Mysql的锁机制_数据库_05

 

加锁的方式

显式锁

隐式锁

死锁

死锁是两个事务互相争夺对方资源,并锁定对方请求的资源

Mysql的锁机制_死锁_06

 

死锁的处理策略:

1.等待超时回滚 当事务被阻塞超过时间后,会报超时错误,自动回滚

2.死锁检测    将持有最少行级的排它锁事务回滚(但是会降低系统的吞吐量,建议在大的并发下,关闭死锁检测)

锁的监控

 监控inndb引擎 

Mysql的锁机制_死锁_07

监控正在被阻塞语句

SELECT * FROM information_schema.INNODB_TRX\G;

Mysql的锁机制_数据库_08

 

Mysql的锁机制_database_09

查询锁等待的情况 

SELECT * FROM performance_schema.data_lock_waits\G

Mysql的锁机制_mysql_10