MySQL存储引擎InnoDB2-锁

2018-03-16  本文已影响48人  梦工厂

锁:为了支持对于共享资源的并发访问,提供数据的完整性和一致性。

1 lock vs latch (这一章讲的是lock)

lock 的对象是事务,用来锁定的是数据库中的对象,如表、页、行.
一般lock的对象仅在事务commit或者rollback后释放(不同隔离级别释放时间不同);


2 InnoDB中的锁
2.1. 锁的类型
2.2. 一致性非锁定读 MVCC

通过读取快照数据,实现读写并行


1)快照数据是该行之前版本的数据,通过undo段来实现。而undo用来在事务中回滚数据,因此快照数据没有额外开销。此外,读取快照数据是不需要上锁的,因为没有事务需要对快照数据进行修改操作。
2)MVCC是默认的读取方式,即读取不会占用和等待表上的锁。
在不同的隔离级别下,读取的方式不同,并不是在每个事务隔离级别下都是采用MVCC读。
此外,即使都是MVCC读,对于快照数据的定义在不同隔离级别也各不相同。
2.3. 一致性锁定读

某些情况下,需要显示对读取操作进行加锁以保证数据的一致性。 (隔离级别更高了,读也要加锁)
对select语句加X锁:select ... for update
对select语句加S锁:select ... lock in share mode

3 外键和锁
4 行锁的算法
  1. Record Lock :单个行记录上的锁
  2. Gap Lock: 间隙锁,锁定一个范围,但不包含记录本身;(锁定的是两边的间隙,不能插进来)
  3. Next-Key Lock: Gap Lock+Record Lock,锁定一个范围,并且锁定记录本身。
    辅助理解 MySQL 加锁处理分析
5 死锁

死锁是指两个或两个以上的事务在执行过程中,因争夺资源而造成的一种互相等待的现象。
解决方法:

  1. 超时机制,优点是简单,缺点是未能考虑事务的执行情况。
  2. 等待图 wait-for-group ,InnoDB采取这种方式。
    等待图 要求数据库保留两种信息:锁的事务链表,事务等待链表。

    根据上述信息构造出一张图,如果存在回路代表存在死锁。
    图中,事务1指向事务2的边定义为:
    (1)事务1等待被事务2所占用的资源;
    (2)事务1最终等待事务2所占用的资源,即事务12在等待相同的资源,而事务1在事务2后边;

    等待图是一种主动的死锁检测机制,每个事务请求锁的时候都会判断是否存在回路,若存在则死锁,通常InnoDB选择回滚undo量最小的事务。
6 补充总结
  1. MySQL Innodb存储引擎的并发控制方式:Lock-Based Concurrency Control + MVCC
    在MVCC并发控制中,读操作可以分成两类:快照读 (snapshot read)与当前读 (current read)。快照读,读取的是记录的可见版本 (有可能是历史版本),不用加锁。当前读,读取的是记录的最新版本,并且,当前读返回的记录,都会加上锁,保证其他事务不会再并发修改这条记录。
  2. 2PL:Two-Phase Locking
    传统RDBMS加锁的一个原则,就是2PL (二阶段锁):Two-Phase Locking
    锁操作分为两个阶段:加锁阶段与解锁阶段,并且保证加锁阶段与解锁阶段不相交。

    2PL就是将加锁/解锁分为两个完全不相交的阶段。加锁阶段:只加锁,不放锁。解锁阶段:只放锁,不加锁。
  3. 分析SQL语句加锁情况:MySQL 加锁处理分析
  4. 参考书《MySQL技术内幕 InnoDB存储引擎 第2版》

@梦工厂 2018.3.16

上一篇 下一篇

猜你喜欢

热点阅读