Mysql锁机制浅谈一

mysql是如何加锁的?

加锁默认是加临键锁,有特殊情况会优化为其他锁

索引上的等值查询

  • 唯一索引,给不存在的记录加锁时,优化为间隙锁
  • 普通索引,向右遍历至最后一个不满足查询条件的值时吗退化为间隙锁

索引上的范围查询

  • 唯一索引:访问到不满足条件的第一个值为止

主键索引

ps:如果是非主键的唯一索引,那么会在大于等于时不会退化为记录锁,并且还会给主键索引加上记录锁

等值查询

image-20241007105137298

范围查询

大于

image-20240921141644217

大于等于

image-20240921141704613

小于或小于等于

image-20240910220350061

非唯一索引

等值查询

image-20240910222723978

范围查询

image-20240910222745401

MySQL的锁机制

在一次事务中加的所有锁,会在事务结束时一起释放。

MySQL中的锁

根据锁的粒度可以划分为:

  • 【全局锁】锁定数据库中的所有表,使其处于只读状态,常用在需要数据备份时
  • 【表级锁】
    1. 【表锁】锁住整张表,粒度较大
    2. 【元数据锁】防止DML和DDL冲突所加的隐式锁
    3. 【意向锁】为避免加表锁时逐行查看行级锁的加锁情况这样的低效操作而加的隐式锁
  • 【行级锁】
    1. 【记录锁】对表中的单条记录加锁。在读已提交和可重复读的事务隔离级别下都支持。
    2. 【间隙锁】对记录与记录之间的间隙加锁。只在可重复读的事务隔离级别下支持。间隙锁是开区间
    3. 【临键锁】对记录以及它与上一条记录之间间隙加的锁。临键锁是左开右闭区间

根据锁的容斥性,还可以分为共享锁S独占锁X

根据锁的思想,还可以分为悲观锁乐观锁

当前读快照读

  • 【当前读】当前读中执行的sql语句都会加锁

    下面四类语句是会加独占锁X的:

    1. select ... from ... for update
    2. insert ...
    3. update ...
    4. delete ...
  • 【快照读】和MVCC相关,不加锁

读锁和写锁的兼容性问题

【读锁】不排斥读锁,排斥写锁

【写锁】对读和写都排斥

注意,间隙锁锁定的是 索引记录之间的“间隙”,而不是锁定具体的记录。它的目的是防止其他事务在锁定的间隙中插入新的记录,从而避免 幻读。所以临键锁和间隙锁是可以同时存在的。

比如这里有两个事务查询:

事务A:

select * from easyjavademo.user where id = 5 for update;

事务B:

select * from easyjavademo.user where id > 6 for update;

6-9有临键锁,5-9有间隙锁,换句话说,间隙锁与间隙锁不冲突,这里可以不谈读写锁的兼容性问题

image-20240921190741879

表1

image-20240921190738010

意向锁

​ 为避免加表锁时逐行查看行级锁的加锁情况这样的低效操作而加的隐式锁。需要注意的是:意向锁是表级锁,是对整个表加的

比如:

​ 当事务A执行一个update语句时,会加目标记录加X型行锁,也会给整个表加X型意向锁(IX)

​ 当事务B想给表加表 锁,会先查看表中有无意向锁,如果没有,则可以直接加表锁;如果有,则要考虑事务B要加的锁与当前意向锁是否兼容,兼容方可加。

加锁分析

如何看一个事务加了什么锁?

select * from performance_schema.data_locks;

其中:

  • lock_type字段说明锁的粒度,如全局锁、表级锁、行级锁;

  • lock_mode说明锁的类型。加锁默认一般是临键锁,有特殊情况会优化为其他锁,字段说明如下:

    1. SX这样无特殊说明的,就是临键锁
    2. REC_NOT_GAP这样,意为没有间隙记录,说明加的是记录锁
    3. GAP说明加的是间隙锁
    4. INSERT_INTENTION插入意向锁
  • index_name说明这个锁加在了哪个字段上

  • lock_data被锁住的区间右值,即上界

案例:

对于上面的表一:(id主键,sort二级唯一索引)

各语句加锁情况如下:

image-20240921205913475

image-20240921205919191

image-20240921205931036

image-20240921205938144

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值