MySQL基础(MySQL锁)

5、MySQL锁

5.1 全局锁

5.1.1 全局锁概念

锁定数据库中的所有的表。最典型的场景就是做全库数据备份的时候,对所有的表都进行了锁定,从而来保证数据的一致性和完整性。

5.1.2 全局锁语法

# 锁库
flush tables with read lock;
# 解除锁定
unlock tables;

全局锁很重,影响面很广,会导致整个业务系统的停止工作。如果我们使用的是主从数据库那么就会造成主从数据同步延时,我们在InnoDB引擎上还可以通过加上参数--single-transaction来完成不加锁的一致性数据备份。

5.2 表级锁

5.2.1 表级锁概念

每次操作锁住整张表,每次锁表的颗粒度很大,容易导致锁冲突。表级锁又分为三类,表锁、元数据锁、意向锁。

5.2.2 表锁

表锁分为两类,表共享读锁(read lock)、表独占写锁(write lock)。表锁语法:

# 加锁
lock tables table_name read/write;
# 释放锁
unlock tables / 客户端断开连接

5.2.2.1 表共享读锁(read lock)

表共享读锁(read lock) 不会阻塞其他客户端的读,但是会阻塞写。

5.2.2.2 表独占写锁(write lock)

表独占写锁不仅会阻塞其他客户端的读还会阻塞其他的客户端的写。

5.2.3 元数据锁(meta data lock)

元数据锁是MySQL自动加的锁无需我们手动控制。它存在的作用就是保证增删改查语句和修改表结构语句不发生冲突,保证读写的正确性。也就说在做增删改查的时候不允许修改表结构。查看元数据锁可以到表performance _schema.metadata _locks中查看。

5.2.4 意向锁

意向锁就是在进行增删改的过程中防止有其他客户端进行锁表的操作,如,根据主键update一条数据的时候会产生一个行级锁,如果此时进行锁表的操作,那么MySQL就会逐条记录的去查看有没有锁冲突,毫无疑问的是这个时候性能很差,这个时候就引入了意向锁,意向锁对整个表进行了加锁,如果想要进行加表锁的操作就必须等待这个意向锁释放才能成功。

意向锁添加语句:

#  意向共享锁 (IS)
select ··· lock in share mode
# 意向排他锁
insert、delete、update、select ··· for update

意向共享锁(IS)和表锁共享锁兼容(read),与表锁排他锁(write)互斥。

意向排它锁(IX)与表锁共享锁(read)和表锁排他锁(write)都互斥。

5.3 行级锁

5.3.1 行级锁概念

每次操作锁住对应行的数据,锁定颗粒度最小,发生锁冲突的概率最低,并发性能最好。行级锁主要分为三类,行锁(Record Lock)、间隙锁(Gap Lock)、临键锁(Next Key Lock)。

行锁:锁定单个行记录的锁,防止其他事务对这个记录进行update和delete。

间隙锁:锁定索引记录间隙(不含该条记录),确保索引间隙记录不变,防止其他事务在这个间隙进行insert从而产生幻读。

临键锁:行锁和间隙锁的组合,同时锁住数据并锁住间隙前面的数据。

5.3.2 行级锁分类

5.3.2.1 行锁

行锁分为共享锁(S)和排他锁(X)。

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

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

MySQL基础(MySQL锁)

MySQL基础(MySQL锁)

5.3.2.2 间隙锁

在默认隔离级别下,InnoDB使用临键锁进行搜索和索引扫描,以防止幻读。

  1. 索引上的等值查询(唯一索引),给不存在的记录加锁时,优化为间隙锁。
  2. 索引上的等值查询(普通索引),向右遍历时最后一个值不满足查询需求时,next-key lock退化为间隙锁。
  3. 索引上的范围查询(唯一索引)--会访问到不满足条件的第一个值为止。

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

发表评论
留言与评论(共有 0 条评论) “”
   
验证码:

相关文章

推荐文章