锁
-
锁机制用来管理对共享资源的并发访问,同时提供数据的完整性和一致性(表锁、页锁、行锁)
-
lock的适用对象是事务,用来锁定的是数据库中的表页行。并且一般lock的对象仅在事务commit或者rollback知乎进行释放。同时lock具有死锁检测机制。保护的是数据库的内容
-
latch适用对象是线程,是一种锁定时间非常短的锁,分为mutex和rwlock(互斥量和读写锁)。目的是用来保证并发线程操作临界资源的正确性。没有死锁检测机制。保护的是内存数据结构
-
-
两种标准的行级锁
- S lock 共享锁:允许事务读一行数据
- X lock:允许事务删除或者更行一行数据
-
两个事务同时获得某一行的S lock,是可行的,称为锁兼容(lock compatible)
-
读写锁并不只是针对行,行表都成
-
-
多粒度锁机制:允许事务在行级、表级上的锁同时存在。
-
意向锁:将锁定的对象分为多个层次,意味着事务希望在更细的粒度加锁
-
将上锁的对象看成一颗树,那么对最细粒度的叶子上锁之前,首先需要对粗粒度的对象上锁
如果对粗粒度上锁导致等待,说明当前对象被其他锁锁定。举例来说,在对记录r加X锁之前,已经有事务对表1进行了S表锁。现在当前事务要对表1加上IX以为记录r上X锁。这时需要等待前一个事务释放锁
-
InnoDB的意向锁都是表级锁。支持的两种意向锁:
- 意向共享锁(IS lock):事务想要获得一张表某几行的共享锁
- 意向排他锁(IX lock):事务想要获得一张表中某几行的排他锁
-
-
意向锁就像是一个intermediary lock,在存在行级锁和表级锁的情况下,事务 T 想要对表 A 加 X 锁,就需要先检测是否有其它事务对表 A 或者表 A 中的任意一行加了锁,那么就需要对表 A 的每一行都检测一次,这是非常耗时的。所以意向锁大大提高了并发效率
-
一致性非锁定读(consistent unlocking read):
事务读取某一行,碰到排他锁,这时去读快照里的数据,并且不需要锁定读(没有事务要去修改快照数据)。快照数据是之前版本的数据,通过undo段来实现的。这是一种多版本并发控制MVCC
-
自增长锁:
- 外键:InnoDB会自动对外键列添加索引,可以避免表锁。
- 对于外键值的插入或者更新,会先尝试给父表加S锁。
-
锁的算法:InnoDB有三种行锁的算法
- Record Lock:单个行记录上的锁
- Gap Lock:间隙锁,锁定一个范围,但不包含记录本上
- Next-Key Lock: 1+2,锁住范围+记录本身。
- Record lock总是会去锁住索引记录。如果没有索引,则锁主键(主键本身就是一个索引)
- 锁升级:将低粒度锁聚集,自动升级为高粒度的锁(如很多行锁聚集,则自动升级成页锁或者表锁)