关于mysql:mysql那些事儿mysql锁总结

45次阅读

共计 3354 个字符,预计需要花费 9 分钟才能阅读完成。

图片: https://uploader.shimo.im/f/y…

往期文章举荐

  • mysql 那些事儿 | 深入浅出 mysql 索引(上)
  • mysql 那些事儿 | 深入浅出 mysql 索引(下)
  • 为什么 Mysql 用 B + 树做索引而不必 B - 树或红黑树?
  • mysql 那些事儿 |mysql 事务隔离机制及其原理
  • 校招 mysql 那些事儿 | 日志模块 binlog/redolog/undolog
  • 校招 mysql 那些事 |MVCC 原理机制
  • mysql 那些事儿 |mysql 锁总结

目录

  • 锁定义
  • 锁分类
  • 读锁和写锁
  • 表锁和行锁
  • InnoDB 共享锁和排他锁
  • InnoDB 意向锁和排他锁
  • InnoDB 行锁
  • InnoDB 间隙锁

    • 概念
    • InnoDB 应用间隙锁目标
  • InnoDB 行锁实现形式
  • 闲聊
  • 欢送退出我的公众号【迈莫 coding】一起 pk 大厂

锁定义

锁是计算机协调多个过程或线程并发拜访某一资源的机制。

在数据库中,除了传统的计算资源 (如 CPU, RAM, I/ O 等) 的争用以外,数据也是一种供须要用户共享的资源。锁抵触也是影响数据库并发拜访性能的一个重要因素。

锁分类

  • 从性能上分为乐观锁 (用版本比照来实现) 和乐观锁
  • 从数据库操作的类型分为读锁和写锁(都属于乐观锁)
  • 从对数据操作的粒度分:分为表锁和行锁

读锁和写锁

  • 读锁(共享锁):针对同一份数据,多个读操作能够同时进行而不会相互影响,然而会阻塞写操作
  • 写锁(互斥锁):以后写操作没有实现前,它会阻断其余写锁和读锁

表锁和行锁

表锁

  • 每次操作时会锁住整张表。开销小,加锁快;不会产生死锁;锁定粒度大,产生锁抵触的概率最高;并发度最低;
  • 表锁更适宜于以查问为主,并发用户少,只有大量按索引条件更新数据的利用,如 Web 利用

行锁

  • 每次操作锁住一行数据。开销大,加锁慢;会呈现死锁;锁定粒度最小,产生锁抵触的概率最低;并发度最高;
  • 行级锁只在存储引擎层实现,而 mysql 服务器没有实现。
  • 行级锁更适宜于有大量按索引条件并发更新大量不同数据,同时又有并发查问的利用,如一些 - 在线事务处理 (OLTP) 零碎

InnoDB 共享锁和排他锁

InnoDB 实现了两种类型的行锁:

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

为了容许行锁和表锁共存,实现多粒度锁机制,InnoDB 还有两种外部应用的意向锁(Intention Locks),这两种意向锁都是表锁:

  • 动向共享锁(IS):事务打算给数据行加行共享锁,事务在给一个数据行加共享锁前必须先获得该表的 IS 锁
  • 动向排他锁(IX):事务打算给数据行加行排他锁,事务在给一个数据行加排他锁前必须先获得该表的 IX 锁

InnoDB 意向锁和排他锁

  • 意向锁是 InnoDB 引擎主动加的,不须要用户干涉
  • 对于 UPDATE INSERT DELETE 语句,InnoDB 引擎会主动给波及数据集加排他锁(X)
  • 对于一般 SELECT 语句,InnoDB不会加任何锁
  • 事务能够通过以下语句显式地给后果集加共享锁或排它锁

    • 共享锁(S): SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE。其余 session 依然能够查问记录,并也能够对该记录加 share mode 的共享锁。然而如果以后事务须要对该记录进行更新操作,则很有可能造成死锁。
    • 排它锁(X):SELECT * FROM table_name WHERE ... FOR UPDATE 。其余 session 能够查问该记录,然而不能对该记录加共享锁或排他锁,而是期待取得锁

InnoDB 行锁

  • innoDB 行锁通过索引上的索引项加锁来实现的,这一点 MySQL 与 Oracle 不同,后者是通过在数据块中对相应数据行加锁来实现的。InnoDB 这种行锁实现特点意味着:只有通过索引条件检索数据,InnoDB 才应用行级锁,否则,InnoDB 将应用表锁!
  • 不论是应用主键索引、惟一索引或一般索引,InnoDB 都会应用行锁来对数据加锁。
  • 只有执行打算真正应用了索引,能力应用行锁:即使在条件中应用了索引字段,但是否应用索引来检索数据是由 MySQL 通过判断不同执行打算的代价来决定的,如果 MySQL 认为全表扫描效率更高,比方对一些很小的表,它就不会应用索引,这种状况下 InnoDB 将应用表锁,而不是行锁。
  • 因为 MySQL 的行锁是针对索引加的锁,不是针对记录加的锁,所以尽管多个 session 拜访不同行的记录,然而如果是应用雷同的索引键,是会呈现锁抵触的(后应用这些索引的 session 须要期待先应用索引的 session 开释锁后,能力获取锁)。利用设计的时候要留神这一点。

InnoDB 间隙锁

概念

当咱们用范畴条件而不是相等条件检索数据,并申请共享或排他锁时,InnoDB 会给符合条件的已有数据记录的索引项加锁;对于键值在条件范畴内但并不存在的记录,叫做“间隙(GAP)”,InnoDB 也会对这个“间隙”加锁,这种锁机制就是所谓的间隙锁(Next-Key 锁)。

很显然,在应用范畴条件检索并锁定记录时,InnoDB 这种加锁机制会阻塞符合条件范畴内键值的并发插入,这往往会造成重大的锁期待。因而,在理论利用开发中,尤其是并发插入比拟多的利用,咱们要尽量优化业务逻辑,尽量应用相等条件来拜访更新数据,防止应用范畴条件。

InnoDB 应用间隙锁的目标:

  • 避免幻读,以满足相干隔离级别的要求;满足复原和复制的须要
  • MySQL 通过 BINLOG 录入执行胜利的 INSERT、UPDATE、DELETE 等更新数据的 SQL 语句,并由此实现 MySQL 数据库的复原和主从复制。MySQL 的复原机制(复制其实就是在 Slave Mysql 一直做基于 BINLOG 的复原)有以下特点:

    • 一是 MySQL 的复原是 SQL 语句级的,也就是从新执行 BINLOG 中的 SQL 语句。
    • 二是 MySQL 的 Binlog 是依照事务提交的先后顺序记录的,复原也是按这个程序进行的。

由此可见,MySQL 的复原机制要求:在一个事务未提交前,其余并发事务不能插入满足其锁定条件的任何记录,也就是不容许呈现幻读。

InnoDB 加锁形式

– 隐式锁定:

InnoDB 在事务执行过程中,应用两阶段锁协定:

随时都能够执行锁定,InnoDB 会依据隔离级别在须要的时候主动加锁;

锁只有在执行 commit 或者 rollback 的时候才会开释,并且所有的锁都是在同一时刻被开释。

– 显式锁定:

select ... lock in share mode // 共享锁 
select ... for update // 排他锁 

– select for update:

在执行这个 select 查问语句的时候,会将对应的索引拜访条目进行上排他锁(X 锁),也就是说这个语句对应的锁就相当于 update 带来的成果。

– select for update 的应用场景*

为了让本人查到的数据确保是最新数据,并且查到后的数据只容许本人来批改的时候,须要用到 for update 子句。

– select lock in share mode

in share mode 子句的作用就是将查找到的数据加上一个 share 锁,这个就是示意其余的事务只能对这些数据进行简略的select 操作,并不可能进行 DML 操作。

– select lock in share mode 应用场景*

为了确保本人查到的数据没有被其余的事务正在批改,也就是说确保查到的数据是最新的数据,并且不容许其他人来批改数据。然而本人不肯定可能批改数据,因为有可能其余的事务也对这些数据 应用了 in share mode 的形式上了 S 锁。

– 性能影响

  • select for update 语句,相当于一个 update 语句。在业务忙碌的状况下,如果事务没有及时的 commit 或者 rollback 可能会造成其余事务长时间的期待,从而影响数据库的并发应用效率。
  • select lock in share mode 语句是一个给查找的数据上一个共享锁(S 锁)的性能,它容许其余的事务也对该数据上 S 锁,然而不可能容许对该数据进行批改。如果不及时的commit 或者rollback 也可能会造成大量的事务期待。

闲聊

  • 读完文章,本人是不是和 mysql 锁的 cp 率又进步了
  • 我是迈莫,欢送大家和我交换

文章也会继续更新,能够微信搜寻「迈莫 coding」第一工夫浏览。每天分享优质文章、大厂教训、大厂面经,助力面试,是每个程序员值得关注的平台。

正文完
 0