MySQL锁

MYSQL锁–后面附上的链接是相关的具体介绍


前言

mysql学习很久了,但是对于mysql中的锁机制以及锁的方式类型还是有很多的不了解,下面是听了关于詹哥的课的分享。


一、mysql锁的分类

  • 按照锁的粒度来说,mysql主要包含三种类型(级别)的锁定机制。

1、全局锁:锁的是整个数据库(database),由mysql的SQL layer层(mysql的逻辑架构)实现的。
2、表级锁:锁的是某个table,由mysql的sql layer层实现的。
3、行级锁:锁的是某行数据,也可能锁定行之间的间隙。由某些存储引擎实现

  • 按照锁的功能来分:可以分为共享锁排他锁
  • 共享锁(Shared Locks)S锁

1、兼容性:加了S锁的记录,允许其他事务再加S锁,不允许其他事务再加X锁
2、加锁方式:select....lock in share mode

  • 排他锁(Exclusive Locks)X锁

1、兼容性:加了X锁的记录,不允许其他事务再加S锁或者X锁
2、加锁方式:select....for update

二、各种锁的详解

2.1全局锁

  • 全局锁就是对于整个数据库实例加锁,加锁后整个实例就处于只读状态,后续的MDL的写的语句,DDL语句已经更新的操作的事务提交语句都将被阻塞。其典型的使用场景是做全库的逻辑备份,对所有的表进行锁定,从而获取一致性视图,保证数据的完整性
  • 加全局锁的命令为

mysql>flush tables with read lock;

  • 释放全局锁的命令为如下:也可以断开session的连接,自动释放全局锁

mysql>unlock tables

  • 说到全局锁用于备份这个事情,是比较危险的。因为如果在主库上加上全局锁,则整个数据库将不能写入,备份期间影响业务运行,如果在从库上加全局锁,则会导致不能执行主库同步过来的操作,造成主从延迟。
  • 对于innodb这种支持事务的引擎,使用mysqldump备份时可以使用–single-transaction参数,利用mvcc提供一致性视图,而不使用全局锁,不会影响业务的正常运行。而对于有mylSAM这种不支持事务的表,就只能通过全局锁获得一致性视图,对应的mysqldump参数为 --lock–all–tables。

2.2mysql表级锁

  • mysql的表级锁有四种

1、表读锁
2、表写锁
3、元数据锁 (meta data lock,MDL)
4、自增锁(AUTO-INC locks)

2.2.1表读/写锁

  • 表读写锁就像名称一样的锁,控制着读和写的锁。

2.2.2元数据锁

  • MDL不需要显式使用,在访问一个表的时候会被自动加上。MDL的作用是,保证读写的正确性。你可以想象一下,如果一个查询正在遍历一个表中的数据,而执行期间另一个线程对这个表结构做变更,删了一列,那么查询线程拿到的结果跟表结构对不上,肯定是不行的。
  • 因此,在 MySQL 5.5 版本中引入了 MDL,当对一个表做增删改查操作的时候,加 MDL 读锁;当要对表做结构变更操作的时候,加 MDL 写锁。
  • 读锁之间不互斥,因此你可以有多个线程同时对一张表增删改查。
  • 读写锁之间、写锁之间是互斥的,用来保证变更表结构操作的安全性。因此,如果有两个线程要同时给一个表加字段,其中一个要等另一个执行完才能开始执行

2.2.3自增锁(AUTO-INC Locks)

  • AUTO-INC锁是一种特殊的表级锁,发生涉及AUTO_INCREMENT列的事务性插入操作时产生。

2.3、MySQL行级锁

2.3.1行级锁介绍

  • MySQL的行级锁,是由存储引擎来实现的,这里我们主要讲解InnoDB的行级锁。
  • InnoDB行锁是通过给索引上的索引项加锁来实现的,因此InnoDB这种行锁实现特点意味着:只有通过索引条件检索的数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁!
  • InnoDB的行级锁,按照锁定范围来说,分为四种:

1、记录锁(Record Locks):锁定索引中一条记录。
2、 间隙锁(Gap Locks):要么锁住索引记录中间的值,要么锁住第一个索引记录前面的值或者最后一个索引记 录后面的值。
3、 临键锁(Next-Key Locks):是索引记录上的记录锁和在索引记录之前的间隙锁的组合(间隙锁+记录 锁)。
4、 插入意向锁(Insert IntentionLocks):做insert操作时添加的对记录id的锁

  • innoDB的行级锁,按照功能来说,分为两种:

共享锁(S):允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁。
排他锁(X):允许获得排他锁的事务更新数据,阻止其他事务取得相同数据集的共享读锁和

2.3.2意向锁 Intention Locks

  • InnoDB也实现了表级锁,也就是意向锁,意向锁是mysql内部使用的,不需要用户干预。意向锁和行锁可以共存,意向锁的主要作用是为了【全表更新数据】时的性能提升。否则在全表更新数据时,需要先检索该范是否某些记录上面有行锁。
  1. 表明“某个事务正在某些行持有了锁、或该事务准备去持有锁”
  2. 意向锁的存在是为了协调行锁和表锁的关系,支持多粒度(表锁与行锁)的锁并存,。
  3. 例子:事务A修改user表的记录r,会给记录r上一把行级的排他锁(X),同时会给user表上一把
    意向排他锁(IX),这时事务B要给user表上一个表级的排他锁就会被阻塞。意向锁通过这种方式
    实现了行锁和表锁共存且满足事务隔离性的要求。
  4. 1)意向共享锁(IS锁):事务在请求S锁前,要先获得IS锁 。2)意向排他锁(IX锁):事务在请求X锁前,要先获得IX锁
  • 意向锁的作用

当我们需要加一个排他锁时,需要根据意向锁去判断表中有没有数据行被锁定(行锁)
(1)如果意向锁是行锁,则需要遍历每一行数据去确认;
(2)如果意向锁是表锁,则只需要判断一次即可知道有没数据行被锁定,提升性能。

  • 注意:上了行级X锁后,行级X锁不会因为有别的事务上了IX而堵塞,一个mysql是允许多个行级X锁同时存在的,只要他们不是针对相同的数据行。

2.3.3记录锁(Record Locks)

  • 记录锁, 仅仅锁住索引记录的一行,在单条索引记录上加锁。
  • record lock锁住的永远是索引,而非记录本身,即使该表上没有任何索引,那么innodb会在后台创建一个隐藏的聚集主键索引,那么锁住的就是这个隐藏的聚集主键索引。所以说当一条sql没有走任何索引时,那么将会在每一条聚合索引后面加X锁,这个类似于表锁,但原理上和表锁应该是完全不同的。
-- 加记录共享锁
select * from t1_simple where id = 1 lock in share mode;
-- 加记录排它锁
select * from t1_simple where id = 1 for update;

2.3.4间隙锁(Gap Locks)

  • 区间锁, 仅仅锁住一个索引区间(开区间,不包括双端端点)
  • 在索引记录之间的间隙中加锁,或者是在某一条索引记录之前或者之后加锁,并不包括该索引记录本身。
  • 间隙锁可用于防止幻读,保证索引间的不会被插入数据

2.3.5临键锁(Next-Key Locks)

  • record lock + gap lock, 左开右闭区间,例如(5,8]。
  • 默认情况下,innodb使用next-key locks来锁定记录。select … for update
  • 但当查询的索引含有唯一属性的时候,Next-Key Lock 会进行优化,将其降级为Record Lock,即
    仅锁住索引本身,不是范围。
  • Next-Key Lock在不同的场景中会退化:

2.3.6插入意向锁(Insert Intention Locks)

(1)插入意向锁是一种Gap锁,不是意向锁,在insert操作时产生。
(2)在多事务同时写入不同数据至同一索引间隙的时候,并不需要等待其他事务完成,不会发生锁等待。
(3)假设有一个记录索引包含键值4和7,不同的事务分别插入5和6,每个事务都会产生一个加在4-7
之间的插入意向锁,获取在插入行上的排它锁,但是不会被互相锁住,因为数据行并不冲突。
(4)插入意向锁不会阻止任何锁,对于插入的记录会持有一个记录锁。

2.3.7行锁加锁规则

  • 主键索引
  1. 等值查询
    (1)命中记录,加记录锁。
    (2)未命中记录,加间隙锁。
  2. 范围查询
    (1)没有命中任何一条记录时,加间隙锁。
    (2)命中1条或者多条,包含where条件的临键区间,加临键锁
  • 辅助索引
  1. 等值查询
    (1)命中记录,命中记录的辅助索引项+主键索引项加记录锁,辅助索引项两侧加间隙锁。
    (2)未命中记录,加间隙锁
  2. 范围查询
    (1)没有命中任何一条记录时,加间隙锁。
    (2)命中1条或者多条,包含where条件的临键区间加临键锁。命中记录的id索引项加记录锁。

三、相关文档(自己看)

  • 1.全面了解mysql锁机制(InnoDB)与问题排查

https://juejin.cn/post/6844903668571963406

  • 2.MySQL 三万字精华总结 + 面试100 问,和面试官扯皮绰绰有余(收藏系列)

https://juejin.cn/post/6850037271233331208


总结

上面主要讲的是mysql几个锁的概念,用来自己想看的时候随时可以看不需要自己去查看相关文档。下面是自己看的文档地址:
1.全面了解mysql锁机制(InnoDB)与问题排查 https://juejin.cn/post/6844903668571963406
2.MySQL 三万字精华总结 + 面试100 问,和面试官扯皮绰绰有余(收藏系列) https://juejin.cn/post/6850037271233331208

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值