Mysql锁机制原理innodb

前言:

唏嘘唏嘘,提前批投了一手字节,简历就被筛选掉了,无时无刻不在提醒我是个小菜鸡=。=,老老实实更新了。

锁的粒度

  • 行锁
    只针对操作的当前行进行加锁。并发情况下,产生锁等待的概率较低,支持较大的并发数,但开销大,加锁慢,而且会出现死锁。
    (在InnoDB中使用行锁有一个前提条件:检索数据时需要通过索引!因为InnoDB是通过给索引的索引项加锁来实现行锁的。)
  • 表锁:
    表锁的锁定颗粒度在MySQL中是最粗的,InnoDB、MyISAM引擎中都有应用,对当前整张表加锁。不适合高并发的场景,但开销小,加锁快,不会出现死锁,发生锁冲突的概率最大。

锁的类型

行级锁
  • 共享锁:允许事务读取一行数据
  • 排他锁:允许事务删除或者更新一行数据
表级别的锁
  • 意向排他锁:事务想要获得一张表中某几行的共享锁
  • 意向共享锁:事务想要获取一张表中某几行的排他锁
  • 共享锁:允许事务读取整张表数据
  • 排他锁:允许事务删除或者更新整张表数据

表级别的锁兼容性

这里只是列出了表级别锁的兼容性噢。

IS IX S X
IS T T T F
IX T T F F
S T F T F
X F F F F

结合意向锁来分析,意向锁的作用:
innoDB支持多力度锁定,允许事务在行级上的锁和表级上的锁同时存在。
用于查询某个表中是否存在某行被锁的问题,
1)某个事务对某条记录上了个排他锁X之前需要先获取这个表的意向排他锁IX,最后再对记录上排他锁X。
2)然后某个事务也要获取这个表中某条记录的排他锁,先获取这个表的IX锁,IX与IX之间不冲突,所以可以获取
3)若某个事务是要对整个表操作,那么就是要获取这整个表的X锁(表级别的)此时就与IX锁冲突了,当知道该表存在IX锁被获取的时候,就知道表中有记录正在被修改,所以此时等待。
其实就是减免了当要获取整个表级别的排他锁时,需要遍历整个表中的行记录确认没有一条记录正在被锁。

锁的算法

Record Lock: 单个行记录上的锁
Gap Lock:间隙锁,锁定一个范围,但不包含记录本身
Next-Key Lock:Gap Lock+Record Lock,锁定一个范围,并且锁定记录本身。

InnoDb对于行的锁无论是X锁还是S锁都是采用了Next-Key Lock算法,但是对于有唯一性的索引则采用的是Record Lock行级锁。

MVCC多版本控制并发

MVCC只是工作在两种事务级别底下:
(a) Read Committed ;
(b) Repeatable Read;

Read Committed隔离级别: 当前读

像select lock in share mode(共享锁), select for update ; update, insert ,delete(排他锁)这些操作都是一种当前读,为什么叫当前读?就是它读取的是记录的最新版本,读取时还要保证其他并发事务不能修改当前记录,会对读取的记录进行加锁

Repeatable Read隔离界别:快照读

像不加锁的select操作就是快照读,即不加锁的非阻塞读;快照读的前提是隔离级别不是串行级别,串行级别下的快照读会退化成当前读;之所以出现快照读的情况,是基于提高并发性能的考虑,快照读的实现是基于多版本并发控制,即MVCC,可以认为MVCC是行锁的一个变种,但它在很多情况下,避免了加锁操作,降低了开销;既然是基于多版本,即快照读可能读到的并不一定是数据的最新版本,而有可能是之前的历史版本

MVCC多版本控制并发实现原理:

https://blog.csdn.net/SnailMann/article/details/94724197

总结:

本来想一次过写完,发现整理的原理就满多的了,分开两篇来写吧=。=,下一篇放大招了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章