Mysql锁机制

锁机制详解

锁分类

从对数据库操作的类型分为读锁和写锁(都属于悲观锁)、意向锁

乐观锁

多个事务共同更新操作,是通过版本号区分的,乐观锁不会等待

悲观锁

多个事务共同更新操作,需要等待的

乐观锁适合读操作更多的操作,悲观锁比较适合写更多的操作

意向锁

针对表级别的锁,如果事务A已经给表的一行加了意向锁就会有一个标识,事务B想要给这张表做表锁(做表锁的话需要去一行行去看表数据,看每一行是否都没有加锁,都没加锁才能做表锁),这时就可以看到意向锁的标识

从数据操作的粒度分为  表锁、页锁、行锁

表锁

缺点:锁粒度大,发生锁冲突的概率最高,并发度最低,一般用在表迁移上面

好处:开销小,加锁快、不会出现死锁

使用方法:lock table  表名称 read

unlock table 释放表锁

页锁

只有BDB存储引擎支持页锁,页锁就是在页page的粒度上进行锁定

行锁

每次操作一行数据,

缺点:开销大,加锁慢、容易出现死锁

好处:锁粒度最小,发生锁冲突的概率最低,并发度最高

行锁实际上是针对索引加的锁(在索引对应的索引项上做标记),并且该索引不能失效

如果条件不用索引来限制,(RR隔离级别)就会升级为表锁针对这个表加锁 , (RC隔离级别)不会

为什么RR隔离级别 会升级为表锁的原因

因为在RR隔离级别下,需要解决不可重复读和幻读问题,为了防止扫描过的索引被其他事务修改(不可重复读)或间隙被其他事物插入记录(幻读),从而导致数据不一致,所以Mysql解决方案是把所有扫描过的索引记录和间隙都锁上

间隙锁-对索引加锁

间隙锁只有在rr可重复读隔离级别才生效

目的是:(解决幻读问题:A事务读到了B事务新增的数据)

表中的数据不是连续的

1 zhangsan 23

5 lisi 20

20 wangwu 40

(1,5)中间有间隙,是可以被插入2、3、4数据的

Select * from A where id = 10 for update;

那么在id为10这个位置加入间隙锁的话,其他的事务是没有办法对(5,20)中的间隙进行操作的

不过id = 5和id=20是都可以被操作的

临键锁

Select * from A where id >3 and id <= 10 for update;

是行锁与间隙锁的组合

锁等待分析

通过检查InnoDB_row_lock状态变量来分析系统上的行锁的争夺情况

show status like ‘innodb_row_lock’

查看锁等待的详细信息

show engine innodb status;

锁优化实践

1、尽可能让所有数据检索都通过索引来完成,避免无锁引起行锁升级为表锁

2、合理设计索引,缩小缩的范围

3、减少检索条件范围,避免间隙锁

4、控制事务大小,减少锁定资源量和时间长度,涉及事务加锁的sql放在最后执行

5、用低的事务隔离级别

你可能感兴趣的:(Mysql,mysql,数据库)