Mysql进阶-锁

锁是计算机协调多个进程或线程并发访问某一资源的机制。保证数据的一致性

分类

  • 全局锁:锁定数据库中的所有表
  • 表级锁:每次操作锁住整张表
  • 行级锁:每次操作锁住对应的行数据

全局锁

  是对数据库中的每张表进行锁定,后续的DDL和DML语句,都会被阻塞住。
场景:
做全库的逻辑备份(保证数据的一致性、完整性)

# 加锁
flush tables with read lock;
# 解锁
unlock tables;

# 备份的语句:
mysqldump -uroot -p密码 数据库名>备份文件名称.sql# 注意:该语句不是sql语句,是在命令行模式下执行。

特点:

  1. 对主库进行备份的时候,所有的业务都会停摆。
  2. 对从库进行备份的时候,从库不能执行主库同步过来的二进制日志,导致主从延迟。

表级锁

表锁

 在表锁中,又分为两个锁:
  表共享的读锁:允许多用户读数据,但不允许写数据(包括自己)。
  表独享的写锁:允许当前用户读写数据,不允许其他用户读写数据。

# 加锁
lock tables 表名 read/write;
# 解锁
unlock tables/客户端断开

元数据锁

  MDL是系统控制的,不需要手动去加锁。
作用:
  维护表元数据的一致性,在表上有活动事务的时候,不可以对元数据进行写入操作。

一句话:
  避免DML和DDL冲突,保证读写的正确性。(DML:操作表的数据。DDL:表结构相关的操作)

MDL是在Mysql5.5引入的。
在这里插入图片描述
读写锁是兼容的,也就是说:我们可以同时存在对表数据的增删改查。
alter修改表结构的时候加的锁是互斥的。也就是:当我们有其他锁存在时候,alter得等到其他锁释放之后,才能加上互斥锁。

注意:
  开启事务是不会加上的,当我们在事务中执行相关SQL语句的时候,他才能加上对应的锁。

查看元数据锁:

select object_type,object_schema,object_name,lock_type,lock_duration from performance_schema.metadata_locks;

  元数据锁的使用不是仅局限于事务操作内,它可能在任何情况下被 MySQL 系统自动使用以保护关键数据的完整性和一致性。

例如:
使用alter,rename更改表结构的时候,都有可能涉及到元数据锁的使用。

意向锁

意向锁的前提是有行级锁

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

为什么引入意向锁?
  当没有意向锁的时候,我们加了行锁之后,想要加表锁,那么就得在加表锁前去全表扫描,看有没有加行锁,要是加了就阻塞。要是没有加行锁,那么表锁就添加成功。
Mysql进阶-锁_第1张图片
  有了意向锁之后,在加了行锁之后,同时也会给表加一个意向锁。当加表锁的时候,就会检查这个表上边有没有意向锁,如果有就检查和我这个表锁兼不兼容,兼容就直接加锁成功,要是不兼容就阻塞。

意向锁的出现,解决了全表扫描检查行锁时,效率低下的问题。

意向锁的分类:

  • 意向共享锁(IS):与表锁共享锁(read)兼容,与表锁排他锁(write)互斥
  • 意向排他锁(IX):与表锁共享锁(read)进而排他锁(write)都互斥。意向锁之间不会互斥

查看意向锁和行锁:

select object_schema,object_name,index_name,lock_type,lock_mode,lock_data from performance_schema.data_locks;

行级锁

行锁

  锁定单个行记录的锁,防止其他事务对此进行 update 和 delete。在RC(读已提交)、RR(可重复读)隔离级别下都支持。
行锁的分类:

  • 共享锁(s):允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁。
  • 排他锁(x):允许获取排他锁的事务更新数据,阻止其他事务获得相同数据集的共享锁和排他锁。
    Mysql进阶-锁_第2张图片
    Mysql进阶-锁_第3张图片
      在这里我们需要把握住行级锁这个概念,即:锁是给每行加的,每行可以有不同的锁。(不同的行,锁也不同)
  1. 针对唯一索引进行检索时,对已存在的记录进行等值匹配时,将会自动优化为行锁(也就说通过过滤条件为唯一索引的字段进行操作的时候,会自动加行级锁)。
    Mysql进阶-锁_第4张图片

  2. InnoDB的行锁是针对于索引加的锁,不通过索引条件检索数据,那么InnoDB将对表中的所有记录加锁,此时就会升级为表锁。
    Mysql进阶-锁_第5张图片
    name是没有加索引的。

查询行锁的语句(和意向锁一样):

select object_schema,object_name,index_name,lock_type,lock_mode,lock_data from performance_schema.data_locks;

间隙锁

  锁定索引记录间隙(不含该记录),确保索引记录间隙不变,防止其他事务在这个间隙进行insert,产生幻读。在RR(可重复读)隔离级别下都支持。
在这里插入图片描述

  1. 索引上的等值查询(唯一索引),给不存在的记录加锁时,优化为间隙锁。
    加间隙锁,是给和距离他最近的两个间隙加锁。
    Mysql进阶-锁_第6张图片

  2. 索引上的等值查询(普通索引),向右遍历时最后一个值不满足查询需求时,next-key lock退化为间隙锁。
    向右遍历是因为:普通索引有可能相同的索引,得保证我这个找的是它的边界。
    Mysql进阶-锁_第7张图片

  3. 索引上的范围查询(唯一索引)–会访问到不满足条件的第一个值为止。
    Mysql进阶-锁_第8张图片

注意:
  间隙锁唯一目的是防止其他事务插入间隙。间隙锁可以共存,一个事务采用的间隙锁不会阻止另一个事务在同一间隙上采用间隙锁。

临建锁

  行锁和间隙锁组合,同时锁住数据,并锁住数据前面的间隙Gap。在RR隔离级别下支持。
Mysql进阶-锁_第9张图片


如果文章中有描述不准确或者错误的地方,还望指正。您可以留言或者私信我。
最后希望大家多多 关注+点赞+收藏^_^,你们的鼓励是我不断前进的动力!!!
感谢感谢~~~

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