分布式数据库系统中的死锁处理

分布式数据库系统中的死锁处理

全局死锁与等待图

死锁发生的条件

在分布式环境下,由于通讯延迟的不确定性、地域的分布性以及资源和数据的高度共享性等影响因素的存在,使得死锁预防和检测变得极为困难。在分布式计算系统中,有两个以上的进程在并发执行,每个进程都在等待被其它的进程所占用的系统资源而不能继续运行,即导致系统中任何一个进程都无法运行下去(死循环),这就产生了死锁。

当且仅当以下四个条件同时成立时,死锁才会发生:

  • 互斥。同一个资源在同一时刻最多只能被一个进程占用。

  • 占有并等待。必然有一个进程至少占用了系统中的一个资源,同时在等待获取被其他进程占用的资源。

  • 不可剥夺。一个进程不能剥夺被其他进程占用的资源。

  • 循环等待。在等待图中有一个循环。

死锁分类

  • 局部死锁:仅在一个站点上发生的死锁
  • 全局死锁:涉及多个站点的死锁(即等待圈由多个站点组成)

在图中,事务T1在站点A对数据x持有一个锁,又要对站点B的数据y请求封锁,而事务T2在站点B对数据y持有一个锁,又要对站点A的数据x请求封锁。这样就形成了相互等待,两个事务谁也不能继续执行。由于这两个事务不在同一站点,引起全局死锁。

分布式数据库系统中的死锁处理_第1张图片
A站点T1拿着x锁想要y锁,B站点T2拿着y锁想要x锁,相互等待引起全局死锁.

分布式数据库中的数据冗余也会增加更新数据时引起死锁的机会。因为更新时需要对全部副本加拒绝锁,含有副本的每个站点上都有可能等待另一个事务释放锁,但每一个事务只有在它全部完成后才能释放,因此造成全局死锁.

分布式数据库系统中的死锁处理_第2张图片
站点A:存储x和y的副本, 发出事务T1:read(x),write(y)
站点B:存储y和z的副本, 发出事务T2:read(y),write(z)
站点C:存储z的副本, 发出事务T3:read(z),write(x)

写操作必须要锁来保证

A站点:拿着x锁想要y锁
B站点:拿着y锁想要z锁
A站点:拿着z锁想要x锁

概念拓展(锁)

什么是锁?有哪两种锁?

答:
锁是最常用的并发控制机构,是防止其他事务访问指定资源,实现并发控制的一种手段。
排他锁(X写锁):当数据被加上写锁,其他事务不能对该数据进行读和写
共享锁(S读锁):当数据被加上读锁,允许其他事务对该数据进行读,不允许写

等待图

  • 一种用来表示事务之间相互等待关系的有向图, 是分析死锁的有用工具
  • 节点表示事务
  • 带有箭头的有向边表示“等待”关系
  • 如果等待图有回路,就说明有死锁

等待图分类

  • 局部等待图(LWFG)
  • 全局等待图(GWFG)

案例

全局等待图(GWFG)
分布式数据库系统中的死锁处理_第3张图片

T1等待T2释放对y的共享锁(s)
T2等待T3释放对z的共享锁(s)
T3等待T1释放对x的共享锁(s)

换而言之

  • T1拿着x锁想要y锁(两把锁同时拿到T1事务才能完成,x,y两把锁才会被释放)
  • T2拿着y锁想要z锁
  • T3拿着z锁想要x锁

一到6.3 假设四个事务 T1、T2、T3、T4之间的等待关系如下;
T1->T2->T3->T4如果T1与T2运行于站点1,T3与T4运行于站点2,则这两个站点的局部等待图如图所示。注意:仅通过检查这两个局部等待图来找出死锁是不全面的,因为这个死锁是全局的。然而,通过检查全局等待图可以轻松地找出死锁,为区别它们,可把全局等待图中站点之间的等待用点线表示,如图所示。

分布式数据库系统中的死锁处理_第4张图片

处理死锁的策略

有三种处理死锁的策略:

  1. 预防死锁。限制请求,保证前文提到的四个死锁条件中至少有一个不能发生, 从而预防死锁;

  2. 避免死锁。如果结果状态是安全的, 就将资源动态地分给进程。如果至少有一个执行序列使所有的进程都能完成运行, 那么这个状态就是安全的;

  3. 检测死锁和从死锁中恢复, 允许死锁发生, 然后发现并解除死锁。

死锁预防和避免采用一种悲观方法,即认为死锁会经常发生并试图阻止或避免它。虽然死锁避免策略在集中式系统中广为应用,并且有许多算法,但是在分布式系统中很少使用。
这是因为在分布式系统中没有全局时钟,检查安全性状态会涉及到大量进程和资源的计算,从而引起昂贵的开销。死锁检测和恢复使用乐观方法,然而这种方法对于死锁发生频繁的应用程序可能并不有效。

解决死锁的方法

  • 死锁预防,使引起死锁的必要条件不成立
  • 所有资源排序, 按资源序列申请
  • 将所有并发事务排序, 按标识符或开始时间
  • 有死锁危险时,事务退出已占有的资源,有两种方法
  • 等待-死亡(Wait-Die):总是重启较年轻的事务(非占先权)
    -受伤-等待(Wound-Wait) :年轻的等待年老的, 较年轻的重启,而重启事务并不一定是目前正申请的事务 (占先权)

死锁预防

等待-死亡模式(非占先权)

  • 如果Ti对已被Tj封锁的一数据项请求封锁的话,则只有在Ti比Tj年老时(Ti,才允许Ti等待
  • 如果Ti比Tj年轻(Ti>Tj),则Ti被终止并带有同一时间戳重新启动
  • 最好总是重新启动较年轻的事务
  • 允许较年老的事务去等待已持有资源的较年轻的事务
  • 但不允许较年轻的事务去等待较年老的事务

受伤-等待模式(占先权)

  • 如果Ti对已被Tj封锁的一数据项请求封锁的话,则只有在Ti比Tj年轻时(Ti>Tj),才允许Ti等待
  • 否则,Ti比Tj年老(Ti
  • 只有年轻的等待年老的

总结

非占先权:

年老的事务允许等待年轻的事务,如果年轻事务需要年老事务的锁,则直接终止重启.某种意义上事务变老就失去了优先权.
由于年老事务持锁时间,年轻事务可能会被重启多次.

占先权:

年老的事务需要年轻事务的锁时,年轻事务就必须无条件服从终止重启,将自己的锁释放,成就年老的事务.某种意义上事务变老就增加了优先权.
由于年轻事务遇到年老事务就会主动让位,释放所有的锁重启,所以只会被重启一次.

死锁的检测和解决方法

集中式死锁检测

  • 选择一个站点负责整个系统的死锁检测,死锁检测器放到这个站点
  • 每个站点的锁管理器周期性地将本站点的LWFG传送给死锁检测器, 死锁检测器构造GWFG, 并在其中寻找回路
  • 或者,其它每个站点上的锁管理器周期性地把记录本站点上事务的开始时间,对锁的持有、请求情况变化的动态表,发送给负责处理封锁的站点,由它维护一张全局封锁动态表,形成GWFG, 并在其中寻找回路
  • 如果至少包含一条回路,它会选择一个或者多个事务,把它们取消并恢复,释放资源,使得其它事务继续进行。
    -选择的标准是尽可能使撤销并恢复的代价最小,如撤销年轻的事务,撤销占有较少资源的事务,撤销具有最短运行时间的事务,撤销具有最长运行时间的事务等,使系统情况而定

层次式死锁检测

  • 以层次方式组织成员DBMS中的死锁检测器
  • 死锁发生时, 常常只涉及部分站点
  • 层次检测的层次结构与网络拓扑结构有关
  • 减少了对中心站点的依赖性,从而减少了传输开销

基于资源访问类型,各个站点被划分到不同的群组中,并将这些群组以层次方式组织.每个群组中.一个指定的群组负责用集中式算法检测本群组内的死锁.

层次式死锁检测的步骤

  • 树叶是各站点的局部死锁检测器,在本站点建立局部等待图
  • 本站点的死锁检测器找出本站点局部等待图中的任何回路,并把有关潜在全局回路的信息发送给上一层死锁检测器
  • 每个非本地死锁检测器只对它所涉及的紧挨下层进行死锁检测,合并这些接收到的有关潜在全局回路的信息,并找出任何回路
  • 如果还有上层死锁检测器,将经过简化的有关潜在全局回路的信息发送给它上一层死锁检测器,由上一层死锁检测器再进行合并,找出任何全局回路
  • 这样,逐层检测,直到最高层。

层次式死锁检测方法示意图

分布式数据库系统中的死锁处理_第5张图片

分布式检测

分布式死锁的检测更加困难,因为每个站点只有整个系统的一个部分视角,因此,当检测涉及一个以上站点的死锁时,就需要站点之间的协作。在分布式死锁检测算法中,所有的站点共同协作来检测和处理死锁。不像集中式死锁检测算法,分布式死锁检测算法不受单个站点故障的影响,并月没有站点会被死锁检测活动淹没

  • 每个站点的检测死锁责任相同, 站点之间交换信息(LWFG),是为了确定全局死锁
  • EX是指的本地事务正在等待的其他事务所在的还不确定的站点

分布式数据库系统中的死锁处理_第6张图片

局部死锁检测器关注两件事:
  • 如果存在不包括涉及其他站点的边的回路,则此局部死锁可在本地内部解决
  • 如果存在包括涉及其他站点的边的回路,则潜在的分布式死锁及关于此回路的信息必须被传送到新涉及的其他站点的死锁检测器。这种分布式死锁的可能性能够被两个站点检测到如上图。
优化

分布式死锁检测算法需要对每个站点的锁管理器进行统一悠改。这种统一性使得它们更易于实现。然而,这种算法存在大量的信息传输例如,在例图中, 站点1向站点2发送潜在的死锁信息,而站点2也向站点1发送它的潜在死锁信息。这种情况下,两个站点上的死锁检测器都将检测到死锁。除了会导致不必要的信息传输外,还会有一个问题,即每个站点有可能会选择不同的牺牲者事务进行撤销

为了解决这个问题,使用如下规则:令某个站点上的LWFG中可能引起分布式死锁的路径为Ti->...->Tj,仅当ts(Ti)< ts(Tj)时,局部死锁检测器向前传输回路信息(正向传输)。这种方法将传输量减少了一半,则在例图中,站点1有一条传输路径T1->T2->T3,而站点2的传输路径为T3->T4->T1.这样,假定每个事务的下标表示其时标,则仅有站点1会向站点2发送信息。

你可能感兴趣的:(分布式,数据库)