Wanjia Huang

西南交通大学 软件工程

0%

CMU15445-016-Two-PhaseLocking

事务锁(Transaction Locks)

分为两类

  1. Shared Lock 共享锁(S锁):允许多个事务同时读取同一对象的共享锁。如果一个事务持有共享锁,那么另一个事务也可以获取相同的共享锁。
  2. Exclusive Lock 专用锁(X锁):独占锁允许事务修改对象。此锁防止其他事务获取对象上的任何其他锁(S锁或X锁)。一次只有一个事务可以持有独占锁

事务必须从lock manager中请求或更新锁,lock manager根据其他事务当前持有的锁授予或阻止请求。

事务在释放对象的时候要释放锁

lock manager维护一张内部的lock-table,维护的的依据是哪些事务持有哪些锁以及正在等待获取锁的事务

DBMS的lock-table不需要是持久的,因为DBMS崩溃时处于活动状态的任何事务都会自动中止。

Two-Phase Locking

两阶段锁(2PL)是一种悲观锁协议,它使用锁来确定是否允许事务动态访问数据库中的对象。协议不需要知道事务将提前执行的所有查询。 它分为两个阶段

  1. Growing:在成长阶段,每个事务都从DBMS的锁管理器请求它需要的锁。锁管理器授予/拒绝这些锁请求。
  2. Shrinking:事务在释放第一个锁后立即进入收缩阶段。在收缩阶段,只允许事务释放锁。不允许他们请求新的。

就其本身而言,2PL足以保证冲突序列化。 它生成优先级图为非循环的调度。但它很容易受到级联中止的影响,即一个事务中止,而现在必须回滚另一个事务,这会导致工作浪费。

Strong Strict Two-Phase Locking

如果在第一个事务提交之前,事务写入的任何值从未被另一个事务读取或覆盖,则调度是严格的(strict)。 Strong Strict 2PL是2PL的

DeadLock Handling

死锁是等待彼此释放锁的事务循环。处理2PL中的死锁有两种方法:检测和预防。

Deadlock Detection 死锁检测

为了检测死锁,DBMS创建了一个等待图(存在循环则死锁,如下图)

img

其中事务是节点,如果事务Ti正在等待事务Tj释放锁,则存在从Ti到Tj的有向边。系统将周期性地检查等待图(通常使用后台线程),然后决定如何释放它。构造图时不需要Latches,因为如果DBMS在一个过程中错过了死锁,它将在后续过程中找到它。

当DBMS检测到死锁时,它将选择一个“victim”事务中止以打破循环。受害者事务将根据应用程序调用它的方式重新启动或中止。

在选择Victim事务以打破死锁的时候,可以考虑以下属性:

  1. 按年龄(最新或最旧的时间戳)。
  2. 按进度(执行的查询最少/最多)。
  3. 根据已经上锁的项目
  4. 根据回滚所需要的事务数
  5. 根据过去重启事务的次数(避免饥饿)

没有比其他选择更好的选择。许多系统使用这些因素的组合。

选择要中止的受害事务后,DBMS还可以决定回滚事务更改的程度。它可以回滚整个事务,也可以只回滚足够的查询来打破死锁。

Deadlock Prevention 死锁预防

死锁预防不会在事后处理死锁,而是在事务发生之前阻止事务造成死锁。

当一个事务试图获取另一个事务持有的锁(这可能会导致死锁)时,DBMS会杀死其中一个事务。为了实现这一点,根据时间戳为事务分配优先级(较旧的事务具有较高的优先级)。这些方案保证没有死锁,因为在等待锁时只允许一种方向。当事务重新启动时,DBMS重用相同的时间戳。

有两种方法可以在死锁预防下终止事务:

  1. Wait-Die(“Old Waitis for Y Young”):如果请求事务的优先级高于当前事务,则它会等待。否则,它将中止。
  2. Wound-Die(“Young Waitis for Old”):如果请求事务的优先级高于当前事务,则当前事务中止并释放锁。否则,请求事务将等待。

Lock Granularities 锁粒度

如果每次更新一个元组就请求一个锁,那么对于大数据的更新来说,锁请求和释放的开销对于DBMS来说是不可以接受的,因此我们可以改变锁的粒度,比如在表上获取一个具有10亿元组的锁,而不是10亿个单独的锁。

————粒度上可以分为表级锁和行级锁

————为什么会用到意向锁: 当我们向一张表加入表级锁的时候,这时候我们必须去表中每一行去遍历,看看对应的行是否已经用到对应的锁,这时候如果数据库中的数据海量的话,想要完成这个任务的难度就非常的大,因此可以在原有的X锁和S锁上引入意向锁IX锁、IS锁

获得锁(获得对象锁):

IX –表示 如果有事务想获得数据对象X锁之前,先获得表IX锁

IS – 表示如果事务想要获得数据对象S锁之前,先获得表IS锁

加锁(加入表级锁):

如果事务对表加X锁,看看有没有其他的事务对表加锁(S/X/IS/IX)如果有的话,加锁失败

  • 任意 IS/IX 锁之间都是兼容的,因为它们只是表示想要对表加锁,而不是真正加锁;
  • S 锁只与 S 锁和 IS 锁兼容,也就是说事务 T 想要对数据行加 S 锁,其它事务可以已经获得对表或者表中的行的 S 锁。

Intention lock允许在共享模式或独占模式下锁定更高级别的节点,而无需检查所有子节点【每一行】。如果节点处于意图模式,则在树的较低级别执行显式锁定。

  1. Intention-Shared(IS):表示在较低级别使用共享锁进行显式锁定。
  2. Intention-Exclusive (IX):指示使用排他锁或共享锁在较低级别进行显式锁定。
  3. Shared+Intention-Exclusive (SIX):以该节点为根的子树在共享模式下被显式锁定,并且显式锁定在较低级别上使用独占模式锁进行。

————如果另一个任务试图在该表级别上应用共享或排它锁,则受到由第一个任务控制的表级别意向锁的阻塞。第二个任务在锁定该表前不必检查各个页或行锁,而只需检查表上的意向锁(不用遍历每一行,而是检查该表的表级Intention lock