MySQL中的锁

分类:

在MySQL中按照锁的粒度,可将锁分为全局锁,表级锁,行级锁。

全局锁:针对某一数据库加的锁。

表级锁:针对某一张表加的锁。

行级锁:针对某一张表中的某一行加锁。

先附上一张思维导图,对MySQL中锁的分类加以概括:

 接下来将逐一介绍MySQL锁体系中的锁。

全局锁:

当我们给某个数据库加上全局锁,在持有锁的过程中,允许对该库的所有表进行查,但是其他的增加,删除,修改操作都将处于阻塞状态。这样做的目的是保证数据的一致性,完整性。典型应用是在数据库备份。

-- 给数据库加锁
flush tables with read lock;
-- 执行数据库备份操作,直接在window命令执行
mysqldump -uroot -p_____ 数据库名 存储位置;
-- 释放锁
unlock tables;

以上是对全局锁的应用。但在实际开发中我们的数据库不可能部署在一台机器上,会采用主从部署,这样就会存在问题 :

如果从主库上备份,那么在备份期间都不能执行更新,业务基本上就得停摆。

如果在从库上备份,那么在备份期间从库不能执行主库同步过来的二进制文件(binlog),从导致主从延迟。

那么此时我们可以在备份语句后加--single-transcation参数来完成不加锁的一致性数据库备份。加上--single-transcation实际上就是拉取某一时刻的快照,然后将其备份。

表级锁:

分类:

可以将表级锁分为:

  • 表锁
  • 元数据锁(meta data lock,MDL)
  • 意向锁

 表锁:

表锁又可以分为:

  • 表共享读锁:当前客户端可读,不可写,其他客户端可读,写阻塞
  • 表独占写锁:当前客户端可读可写,其他客户端读写阻塞
-- 加锁
lock tables 表名 read/write;
-- 解锁
unlock tables;

元数据锁:

元数据说白了就是维护表结构的一张表。设立元数据锁为了防止DDL与DML的冲突,保证读写的正确性。元数据锁加锁过程是系统自动控制,无需显示使用,在访问一张表时候自动加上。

当读数据时,加上SHARED_READ锁,此时其他事务可以修改。在执行修改时,加上SHARED_WRITE锁,此时读可以操作。但是不可以修改表结构。EXCLUSIVE与其他锁都互斥。

意向锁:

我们可以想以下这样的操作,在加表锁之前需要检查行记录是否加锁,如果有加锁就需要等待锁释放以后再进行表锁的后续操作。此时检查行锁的操作,就需要从表的第一行向下逐一进行,直到最后一行记录。这样的话效率会表较低,因此引入了意向锁。

意向锁解决表锁和行锁的冲突问题,减少了表锁的检查。

  • 意向共享锁(IS):由语句select---lock in share mode添加 ,与表锁排他锁(write)互斥。
  • 意向排他锁(IX):由insert,update,delete,select--for update添加,与表锁read,write都互斥。
  • 意向锁之间不互斥。 

行级锁:

注意:InnoDB的数据时基于索引组织的,行锁是通过对索引上的索引项加锁来实现的,而不是对记录加的锁。

行级锁可以分为:

  • 行锁:锁定单个记录的锁,防止其他事务对此行进行update和delete。在RC RR隔离级别下支持。
  • 间隙锁:锁定索引记录的间隙,不含该记录,确保索引间隙不变,防止其他事务进行insert,产生幻读。在RR(可重复读)隔离级别下都支持。
  • 临键锁:行锁和间隙锁的组合,同时锁住数据,并锁住数据前的间隙。在RR隔离级别下支持。

 行锁:

共享锁:允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁。

排他锁:允许获取排他锁的事务更新数据,阻止其他事务获得相同数据集的共享锁和排他锁。

当前锁类型 \ 请求锁类型

S(共享锁)

X(排他锁)

S(共享锁)

兼容

冲突

X(排他锁)

冲突

冲突

在执行INSERT UPDATE DELETE SELECT...FOR UPDATE的时候加的是排他锁。

在执行SELECT ... LOCK IN SHARE MODE加的是共享锁。

SQL

行锁类型

说明

INSERT

排他锁

自动加锁

UPDATE

排他锁

自动加锁

DELETE

排他锁

自动加锁

SELECT

不加锁

SELECT...LOCK IN SHARE MODE

共享锁

手动加上LOCK IN SHARE MODE

SELECT...FOR UPDATE

排他锁

手动加上FOR UPDATE

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

间隙锁/临键锁:

间隙锁只对记录之间间隙锁住,而临键锁对记录和间隙加锁。

间隙锁

间隙锁只对记录之间的间隙锁住,触发条件是当进行范围查询时未命中记录,查询条件必须命中索引,间隙锁只会出现在RR事务级别中,是为了防止幻读的产生。遵循左开右闭。

临键锁:

临键锁将查询出来的记录锁住,同时把该记录之间的间隙以及相邻的下一个区间也锁住。

触发条件是:范围查询并命中,查询命中了索引。

作用:避免了在范围查询时出现脏读,出复读,幻读等问题。加上临建锁之后,范围查询区间不允许数据的修改和插入。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值