前言

本文讲述mysql锁定义,lock与latch区别,Innodb中的锁,强制开启S/X锁,自增长锁,行锁的3中算法,锁降级等,次要参照来自《MYSQL技术底细 第2版》这本书,以及参杂了本人的一些了解。

锁定义/作用

为反对对 共享资源 的并发拜访,保证数据的一致性完整性,数据库所提供的一种束缚机制。不同的数据库和不同的引擎有着不同实现形式及反对度,可分为行,页,表锁。(MyISAM是表锁,SQL SERVER是行级锁,InnoDB默认也是行级锁)

行锁页锁表锁
MyISAM
Innodb
BDB
SQL Server

前三个都是MYSQL的不同引擎。

lock与latch(门闩shuan)

latch实用于短期锁定的轻量级锁 (门闩不防盗嘛),锁定工夫过长时,性能会十分差。

lock的对象是事务,锁定的是数据库中的对象:行、页、表,锁在commit或rollback时才会开释。
latch分为mutex(互斥锁)和rwlock(读写锁),用于保障并发线程操作临界资源(能够了解为共享资源)的正确性。

latch是面向数据库系统底层的,目前没找供用户开发的api,除非DBA,一般开发者根本用不到,理解即可。
locklatch
对象事务线程
持续时间整个事务临界资源
模式行,页,表锁mutex,rwlock
保留在lock manager的哈希表中数据结构的对象中
mysql innodb中:    查看latch命令: `show engine innodb latch`    查看lock命令: `show engine innodb status`

Innodb引擎中的锁

innodb反对行锁和表锁(不反对表锁),默认为行锁。

两种行级锁:

  1. 共享锁(S lock):容许事务读1行
  2. 排他锁(X lock):容许事务删除或更新1行

在A取得S锁后,B可获S锁,但不能加X,否则A会阻塞。(读不影响数据)
在A取得X锁后,B不能再取得任何锁。(批改必须独占)

S锁能够了解为读锁,X锁能够了解为独占锁,且X优先级高于S。

Innodb反对多粒度锁定,容许行级、表级上的锁同时存在。(Innodb不反对页级锁)为此推出一种新的锁形式意向锁(Intention Lock):将锁定的对象分为多个档次,以满足事务在更细的细粒度上加锁。

一句话概括就是,对下层对象(页,表)加同样的意向锁(IS/IX)。同样的意思就是记录加S,下层对象就加IS;同理,记录加X,下层对象就加IX。

所有兼容状况:(兼容就是能获取,不兼容就是要期待阻塞)
很显著,是对称矩阵哦

一致性非锁定读

一致性非锁定读(consistent nolocking read):指的是在读取被加X锁的行时,不须要期待行锁的开释,会去读它的快照(snapshot)。
一个行有多个快照数据,到底读哪一个呢?
READ COMMITED是读最新的,READ REPEATEABLE(Innodb默认隔离级别)是读的是本人事务begin前的。(这里的场景是开启两个事务,一个查,一个改,有先后。)READ COMMITD会毁坏隔离性(Isolation)

一致性锁定读--强制开启锁

尽管可反复读(默认隔离级别)保障了隔离性,但为了确保数据的一致性,咱们能够显式强制加锁

  • SELECT ... IN SHARE MODE
  • SELECT ... FOR UPDATE

下面的in share mode是加的S锁。for update是加的X锁。

自增长锁

对字段设置auto_incrment时,自增计算器会保留在表中,锁会在insert语句之后,事务commit之前开释。(非凡的机制,为进步插入性能,没有抉择事务完结再开释,而是Insert后)。前面MYSQL还新增了innodb_autoinc_mode来进一步管制自增长。

注:Innodb下自增列必须是索引,而且是索引的第一列(组合索引状况下),否则抛出异样。MyISAM没有这要求。

行锁的3种算法

  • Record Lock :记录锁,锁定本人的记录
  • Gap Lock:沟锁,锁本人左近的范畴,不包含本人记录(开区间)
  • Next-key Lock:范畴+本人,Record+Gap联合(闭区间)

Record Lock是锁住索引记录,主键也是索引之一。
Next-key是行查问select默认采纳的锁算法,如有索引:10,13,20。则锁区间为:(-∞,10],(10,13],(13,20],(20,+∞)。
显知,gap的话就蕴含本人,]变成了)。

next-key这里的next指的就是右区间为闭区间,推理:previous-key指的是左区间闭合。
注:主动降级:若索引中含有惟一属性(**惟一**索引),则next-key会主动降级为record-key。(范畴锁——>只锁本人)

next-key机制的创造是为了解决Phantom problem(幻像问题),是的mysql能够不到serializable就能够解决幻读。
幻像:一个事务A在未提交时,两次sql的执行的后果的数据条数不一样,B向其中批改的数据被A在第二次读走了。违反了隔离性。
脏读: A读到了B中未提交的数据,若B之后回滚了,则读到了脏数据。
不可反复读: B对A读到的值进行了批改,A第二次读到的数据值变了。

锁降级(lock escalation)

定义:锁的粒度升高。如:行锁——>页锁——>表锁

作用:锁是罕见资源,降级是为了提高效率,避免零碎应用太多内存来保护锁。

Innodb存储引擎不存在锁降级。因为它不是依据记录来产生行锁,而是依据事务拜访的每个页来治理锁,采纳位图形式。锁住一个页的一条与锁住多条的开销一样。

这里的`页来治理锁`和下面`innodb不反对页锁`有点绕,我也没了解,我前面去查证一下。