MySQl 面试重点_6.MySQL 锁机制总结

文章目录

  • 一, 锁概述
  • 二, 锁的分类
      • 2.1 从数据的操作类型角度分为: `读锁`和`写锁`
      • 2.2 从数据的操作力度(锁的粒度)角度分为: `表锁`和`行锁`, `页锁`
        • A. 表锁:
          • a. 意向锁
          • b. 自增锁(AUTO-INC)
          • c. 元数据锁(MDL)
        • B. 行锁:
          • a. 记录锁(Record Locks)
          • b. 间隙锁(Gap Locks)
          • c. 邻键锁(Next-Key Locks)
      • Q: InnoDb行锁到底锁的是什么?
      • 2.3 从对待锁的态度划分为: `乐观锁`和`悲观锁`
        • A. 悲观锁(Pessimistic Locking)
        • B. 乐观锁
        • 悲观锁和乐观锁的使用场景
  • 二, 使用: 读锁/共享锁(S)与写锁/排它锁(X)
    • 2.1 共享锁
    • 2.2 排它锁
  • 三, 验证: 意向共享锁(IS)和意向排他锁(IX)
  • 四, 行锁的算法
  • 五, 总结

一, 锁概述

  • 锁是计算机协调多个进程或线程并发访问某一资源的机制

MySQl 面试重点_6.MySQL 锁机制总结_第1张图片

二, 锁的分类

  • 按照对数据的操作类型分为: 读锁, 写锁;
    -))))))))))))))))))))))))))))))))))))))))))))
  • 按照对**数据的操作力度(锁的粒度)**分为: 表锁, 行锁;
  • 按照对待锁的态度分为悲观锁, 乐观锁;

2.1 从数据的操作类型角度分为: 读锁写锁

读锁:

又称为共享锁(Share Lock), 针对同一份数据, 多个读操作可以同时进行而不会相互影响;

写锁:

又称为排他锁(Exclusive Lock), 当前写操作没有完成前, 它会阻断其他写锁和读锁;

  • 对于InnoDB引擎, 读锁和写锁既可以加在表上, 也可以加在行上;

MySQl 面试重点_6.MySQL 锁机制总结_第2张图片

2.2 从数据的操作力度(锁的粒度)角度分为: 表锁行锁, 页锁

为了尽可能提高数据库的并发度,每次锁定的数据范围越小越好,理论上每次只锁定当前操作的数据的方案会得到最大的并发度,但是管理锁是很耗资源的事情(涉及获取、检查、释放锁等动作)。因此数据库系统需要在高并发响应和系统性能两方面进行平衡,这样就产生了“锁粒度(Lock granularity)”的概念。

对一条记录加锁影响的也只是这条记录而已,我们就说这个锁的粒度比较细;其实一个事务也可以在表级别进行加锁,自然就被称之为表级锁或者表锁,对一个表加锁影响整个表中的记录,我们就说这个锁的粒度比较粗。锁的粒度主要分为表级锁、页级锁和行锁

A. 表锁:

该锁会锁定整张表,它是MysQL中最基本的锁策略,并不依赖于存储引擎(不管你是MySQL的什么存储引擎,对于表锁的策略都是一样的),并且表锁是开销最小的策略(因为粒度比较大)。由于表级锁一次会将整个表锁定,所以可以很好的避免死锁问题。当然,锁的粒度大所带来最大的负面影响就是出现锁资源争用的概率也会最高,导致并发率大打折扣。

  1. 偏向MyISAM存储引擎, 开销小, 加锁快;
  2. 锁定力度大, 发生所锁冲突的概率最高, 并发度最低;

MySQl 面试重点_6.MySQL 锁机制总结_第3张图片

a. 意向锁

意向锁存在的意义:

  1. 如果没有意向锁的话,则需要遍历所有整个表判断是否有行锁的存在,以免发生冲突
  2. 如果有了意向锁,只需要判断该意向锁与即将添加的表级锁是否兼容即可。因为意向锁的存在代表了,有行级锁的存在或者即将有行级锁的存在。因而无需遍历整个表,即可获取结果.

MySQl 面试重点_6.MySQL 锁机制总结_第4张图片

解释: 参见本文
MySQl 面试重点_6.MySQL 锁机制总结_第5张图片

b. 自增锁(AUTO-INC)
c. 元数据锁(MDL)

MySQl 面试重点_6.MySQL 锁机制总结_第6张图片

B. 行锁:

开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。

a. 记录锁(Record Locks)

MySQl 面试重点_6.MySQL 锁机制总结_第7张图片

b. 间隙锁(Gap Locks)

MySQl 面试重点_6.MySQL 锁机制总结_第8张图片

c. 邻键锁(Next-Key Locks)

MySQl 面试重点_6.MySQL 锁机制总结_第9张图片

临键锁集合了记录锁的锁住某条记录以及 间隙锁的锁住记录附近的范围 两种功能;

Q: InnoDb行锁到底锁的是什么?

MySQl 面试重点_6.MySQL 锁机制总结_第10张图片

综上所述:

  1. InnoDB的行锁是通过给索引上的索引项加锁来实现的,只有通过索引条件进行数据检索,Innodb才使用行级锁。否则,将使用表锁(锁住索引的所有记录)。
  2. 借此我们是不是能联想到,如果我们的删除/修改语句是没有命中索引的,哪么,则会锁住整个表,这在性能上的影响还是挺大的

2.3 从对待锁的态度划分为: 乐观锁悲观锁

从对待锁的态度来看锁的话,可以将锁分成乐观锁和悲观锁,从名字中也可以看出这两种锁是两种看待数据并发的思维方式 。需要注意的是,乐观锁和悲观锁并不是锁,而是锁的设计思想

A. 悲观锁(Pessimistic Locking)

MySQl 面试重点_6.MySQL 锁机制总结_第11张图片

B. 乐观锁

MySQl 面试重点_6.MySQL 锁机制总结_第12张图片

悲观锁和乐观锁的使用场景

MySQl 面试重点_6.MySQL 锁机制总结_第13张图片

二, 使用: 读锁/共享锁(S)与写锁/排它锁(X)

2.1 共享锁

共享锁又称之为读锁, 简称s锁, 顾名思义就是多个事务对于同一数据可以共享一把锁, 都能够访问到数据库,但是只能读不能修改

#加锁方式
select * from users where id = 1 lock in share mode;

#释放方式(即回滚或提交)
rollback/commit;
  • 举例:

2.2 排它锁

排它锁又称为写锁, 简称X锁, 排它锁不能与其他锁并存, 如一个事务获取了一个数据行的排它锁, 其他事务就不能再获取该行的锁(包括共享锁和排它锁), 只有当前获取了排它锁的事务可以对数据进行读取和修改(此时其他事务要读取数据可从快照获取)

#加锁方式
delete update insert 默认加了排它锁

select * from users where id = 1 for update;

#释放方式(即回滚或提交)
rollback/commit;
  • 举例:

MySQl 面试重点_6.MySQL 锁机制总结_第14张图片

三, 验证: 意向共享锁(IS)和意向排他锁(IX)

MySQl 面试重点_6.MySQL 锁机制总结_第15张图片

四, 行锁的算法

MySQl 面试重点_6.MySQL 锁机制总结_第16张图片

行锁算法举例:

五, 总结

MySQL 的 Innodb引擎正是通过上述不同类型的锁,完成了事务隔离:

加 X 锁 避免了数据的脏读
加 S 锁 避免了数据的不可重复读
加上 Next Key 避免了数据的幻读

  • 参考文章: https://mp.weixin.qq.com/s?__biz=MzI1Mzg4OTMxNQ==&mid=100000550&idx=1&sn=8a5cdff008fc1eed7b5c623c1bdf4ed1&chksm=69ccdd6a5ebb547c7b7baf6be78763fc5065e0a58de202f3e25d8d8ed56e6d1c1146332cfec1#rd

你可能感兴趣的:(#,MySQL面试重点,java,算法,面试,排序)