MySQL的锁机制

MySQL的锁机制

从阻塞角度来看

MySQL锁分为共享锁和排他锁,也可以叫读锁和写锁

1.全局锁

对整个数据库进行加锁,加锁后整个实例都处于只读状态 ,典型应用场景就是做全库的逻辑备份,对所有表进行锁定,获取一致性视图,保证数据的完整性
演示:

-- 锁住
flush tables with read lock;
-- 备份 此命令不是sql语句的,在控制台输入
mysqldump -uroot -proot xxx > xxx.sql;
-- 解锁
unlock tables;

弊端:
阻塞太大,比较重的操作,会阻塞更新语句

2.表级锁

每次操作锁住整张表,发生锁冲突的概率高,主要分为表锁;元数据锁MDL,意向锁三类

2.1表锁

对于表锁分为表共享读锁,表独占写锁

-- 加锁
lock tables 表名 .. read/write
-- 释放锁
unlock tabless/客户端断开连接

2.2元数据(表结构)锁 MDL

MDL加锁过程是系统自动控制,无需显式使用,在访问一张表的时候会自动加上,MDL锁主要作用是维护元数据的数据一致性,在表上有活动事务的时候,不可以对元数据进行写入操作
在MySQL5.5中引入了MDL,当对一张表进行增删改查时,加MDL读锁(共享锁),当对表结构进行变更操作的时候,加MDL写锁(排他锁)。

2.3意向锁

如果没有意向锁,如果线程A对表加了行锁,线程B进来相加一个表锁,那他得去先去遍历整个表,找找有没有其他锁,效率就很低

为了避免DML在执行时,加的行锁与表锁冲突,在InnoDB中引入了意向锁,使得表锁不用检查每一行数据是否加锁,使用意向锁来减少表的锁的检查。

当线程A执行DML时,会加行锁同时对整张表加意向锁
这时候线程B进来想加锁就会检查是否与意向锁兼容,不兼容就会被阻塞

3.行级锁

每次加锁对应的行数据,发生锁冲突的概率最低,InnoDB引擎支持,InnoDB的数据是基于索引组织的,行锁是通过对索引上的索引项加锁来实现,而不是对记录加的锁
行级锁分为三类:

  • 行锁:锁住单行记录,防止其他事务更新,RC,RR隔离级别下支持
  • 间隙锁:锁定索引记录间隙,确保索引记录间隙不变,防止其他事务在这个间隙insert,产生幻读
  • 临键锁:行锁和间隙锁的组合,同时锁住数据和数据前边的间隙

3.1行锁

InnoDB实现了两种类型的行锁,共享锁和排他锁,锁住的是一行数据。

InnoDB的行锁是针对索引加的锁,不通过索引条件检索数据,那么InnoDB将对表中的所有记录加锁,此时会升级为表锁

3.2间隙锁

  • 索引上等值查询(唯一索引),给不存在的记录加锁,会优化为间隙锁,当其他事务想插入数据到该不存在的值所在的间隙时(即B+树叶子节点遍历到比要查的值的下一个值之前的间隙),会被阻塞,防止幻读
  • 索引上的等值查询(普通索引),向右遍历时最后一个值不满足查询需求时,next-key lock退化为间隙锁(对于这种普通索引,不唯一,需要锁住这一行,这一行之前之后的间隙都需要锁住,才能保证不幻读)
  • 索引上的范围查询(唯一索引),会访问到不满足条件的第一个值为止,之间的间隙和行记录都会被加锁

间隙锁的目的就是防止其他事务插入间隙,间隙锁可以共存,一个事务采用间隙锁不会影响别的事务在同一个位置插入间隙锁

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

踢足球的程序员·

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值