一. latch 与 lock 简介
latch一般称为闩(shuan)锁,锁定时间必须非常短,否则性能会大幅降低。InnoDB中分为mutex和rwlock,目的是保证并发线程操作临界资源的正确性,并且通常没有死锁检测的机制。
lock的对象是事务,用来锁定数据库中的对象,如表页行等,在事务回滚或者提交后释放,有死锁机制。
二. lock详解
InnoDB存储引擎实现了两种标准的行级锁:
- SLock 读锁
- XLock 写锁
以及对应的表级意向锁
- IS Lock 事务想要获得一张表中某几行的读锁
- IX Lock 事务想要获得一张表中某几行的写锁
-
什么是意向锁?
意向锁的存在是为了在行级加锁的同时,能让更粗粒度,即页、表、库上,加上锁。InnoDB的意向锁没那么复杂,仅仅是在行级加锁的同时,给表加上锁。
InnoDB存储引擎支持多粒度锁定,也就是事务允许在行级和表级上同时加锁,是通过意向锁来实现的。 -
意向锁和标准锁的区别和联系?
意向锁之间都是兼容的,因为意向锁仅仅代表表中有行需要读或者写,如果会和别的锁发生冲突,那么在更细粒度级就会发生。
三. 一致性非锁定读
一致性非锁定读:读取快照数据,所以不需要等待写锁的释放。通过undo段实现。默认读取方式。
- 读提交: 事务提交后,所有进程都可以看到改动。读取最新快照信息。
- 可重复读:在一个事物中重复读一个数据的值,值不变。读取事务开始时的快照信息。
好处:提高了数据库的并发性。
技术:多版本并发控制MVCC。
四. 一致性锁定读
select for update: 对读取的行记录加一个写锁
select lock in share mode: 对读取的行记录加一个读锁
五. 自增长和锁
通过参数innodb_autoinc_lock_mode来决定自增加锁策略,共三种012。默认为1。

六. 外键和锁
对于一个外键列,如果没有显示地对这个列加索引,innodb引擎会自动对其加一个索引,这样可以避免表锁。
对于外键的更新和插入,首先需要查询父表的记录,对父表加一个读锁,如果这时候父表已经有了写锁,则操作被阻塞。
七. 锁的算法
InnoDB有三种行锁算法:
- Record Lock:单个行记录上的锁。 会锁住索引记录,若没有索引,会锁住隐式的主键。
- Gap Lock:间隙锁,锁定一个范围,不包含记录本身。(x, y)
- Next-Key Lock【间隙锁】: Record Lock + Gap Lock (x, y], innoDB对于行查询的默认锁定算法。当查询的索引含有唯一属性时,降级为Record Lock。
innoDB存储引擎会对辅助索引下一个键值,加上gap lock,即辅助索引会锁住前后两个区间 ,目的是为了防止幻象问题。
这里还要重点注意一下,边界值是停下来的值,而不单纯是范围,比如说有四条记录(5, 5), (10, 10), (15, 15), (20, 20) 前者是主键索引,后者是辅助索引。
我们逆序搜索c>=15 && c<=20的时候,会搜到10这条记录,然后会锁死(5, 10),并不是只锁[15, 20]以及相邻的[10, 15]就可以了,要注意搜索终止的位置!!!
八. Phantom Problem 幻象问题
幻象问题是指在同一事务下,连续执行两次同样的sql语句出现了不同的结果。
在默认的可重复读事务隔离级别下,InnoDB采用Next-Key Locking机制来避免幻象问题。
为了提高系统的并发性,可以考虑通过读提交的隔离级别+binlog_format=row的方式来替代间隙锁。
九. 脏读
脏页: 缓冲池中已经被修改的页。不影响数据一致性。
脏数据:还未提交的已经被修改的数据。
脏读:在不同事务下,当前事务可以读到脏数据。
发生隔离级别:读未提交。
读未提交应用场景:replication环境中的不需要精确返回值的slave节点。
十. 不可重复读
不可重复读:读到已经提交的数据。
解决方法:next-key lock算法
十一. 阻塞
参数:
innodb_lock_wait_timeout:控制等待的时间(默认50秒)
innodb_rollback_on_timeout:设定是否在等待超市时对进行中的事务进行回滚操作(默认不回滚)
必须提前决定在出现异常的时候,是对事务进行提交还是回滚。
十二. 死锁
死锁:指两个或两个以上的事务在并发执行过程中,因争夺资源而造成的一种互相等待的现象。发生的概率通常比较小,随事务的数量、每个事务操作的数量、操作数据的集合的增长而增长。
解决方法1:超时
当两个事务互相等待超过一定时间后,将其中一个事务回滚。
解决方法2: 等待图
innodb引擎采用的方法,是一种主动检测死锁的方法。
需要保存两种信息:1. 锁的信息链表 2. 事务的等待链表
边 t1->t2:事务t1等待事务t2占有的资源。
通过dfs检测回路,如果有回路,那么就存在死锁,innodb会回滚undo量最小的事务。
十三. 锁升级
锁升级:将当前锁的粒度降低。行锁->页锁->表锁
目的:保护系统资源,节省维护锁的内存,提高效率。
innodb:不存在锁升级,使用位图方式管理锁,锁多个对象和单个对象开销相同。
本文详细介绍了InnoDB存储引擎中的锁机制,包括latch和lock的区别,行级锁如SLock、XLock以及意向锁ISLock、IXLock的工作原理。讨论了一致性读取(非锁定读和锁定读)以及自增锁策略。还涵盖了外键与锁的关系,死锁的检测与解决方法,以及锁升级的概念。此外,文章还提及了数据库事务的隔离级别,如读已提交和可重复读,以及它们如何影响并发性和数据一致性。
2905

被折叠的 条评论
为什么被折叠?



