首页 理论教育分布式数据库技术:节点故障的处理方法

分布式数据库技术:节点故障的处理方法

【摘要】:我们认为这就是源节点故障。如图10.13所示,其中用圆表示状态,用有向弧表示状态转换,用同心圆表示终止状态。此时,协调者是在WAIT状态发现超时,进行相应处理。这5种情况涵盖了所有需要处理的终止协议。如果在终止所有参与者期间认识到只是协调者节点出现故障,那么可以选举一个新的协调者,并重新启动提交过程。1)协调者节点故障当协调者节点出现故障时,可能会发生如下情况。

本节考虑网络中的节点故障问题。我们希望开发无阻塞的终止协议和独立的恢复协议。

1.终止协议

终止协议负责解决协调者(coordinator)和参与者(participant)在超时情况下的问题。如果在特定时间段里无法从一个源节点等到期待的消息,则目标节点发生超时。我们认为这就是源节点故障。

处理超时的方法和故障计时与故障的类别有关。因此我们需要从不同的方面考虑2PC执行时的故障。如图10.13所示,其中用圆表示状态,用有向弧表示状态转换,用同心圆表示终止状态。

1)协调者超时

在WAIT、COMMIT和ABORT等三种状态下协调者会超时,后两种情况下的处理方式相同,所以这里只要考虑两种情况。

WAIT状态下超时:在WAIT状态,协调者等待参与者的本地决策。决策者不能单边提交事务,因为此时还不满足全局提交规则。但是,它可以决定全局夭折事务,此时的处理是:在日志中写入abort记录,然后向所有的参与者发送global-abort消息。

COMMIT或ABORT状态下超时:此时不知道参与者本地对提交或夭折程序的执行情况,因此只能向还没有响应的参与者不停地发送global-commit或global-abort命令,并等待答复。

2)参与者超时

在INITIAL和READY两种状态下,参与者会超时。

INITIAL状态下超时:此时参与者在等待″prepare″消息。协调者肯定在INITIAL状态出现故障了。超时后参与者可以单边夭折该事务。如果晚些时候″prepare″消息到该参与者,则有两种选择:检查自己的日志,如果找到abort记录,则给予vote-abort响应,或者忽略这个″prepare″消息。此时,协调者是在WAIT状态发现超时,进行相应处理。

READY状态下超时:此时参与者已经选择提交或夭折,但不知道协调者的全局决策是什么。参与者不能单边作决定。因为处于READY状态,参与者必定已经选择了提交,所以不能再单边决定夭折。同样也不能单边提交,因为其他参与者可能选择夭折。结果是只能等待,直到从他方(协调者或其他参与者)获得抉择消息。

现在来看看集中式的通信结构,即参与者不能与其他参与者通信。这时,如果参与者想终结一个事务,必须询问协调者的决策是什么,然后等待,直至接到一个响应为止。如果协调者失败,参与者就会留在阻塞状态,这是我们不期待的。

如果能够让参与者与其他参与者通信,则需要开发一种分布终止协议。参与者在超时时可以简单地询问其他参与者,了解刚才的决策是什么。

假设参与者Pi超时,所有其他参与者Pj采用如下方式响应。

(1)Pj处于INITIAL状态。意味着Pj还未选举,可能还没有收到″prepare″消息,所以它可以单边决定夭折,给Pi答复一个″vote-abort″消息。

(2)Pj处于READY状态。此时Pj已经选择提交事务但是还没有收到全局决策,因此不能帮助Pi终止事务。

(3)Pj处于ABORT或COMMIT状态。在这些状态下,Pj已经单边决定夭折该事务或者已经接收到了协调者按照全局终止做出的决定。因此它可以向Pi发送″vote-commit″或″vote-abort″消息。

现在看看超时的参与者(Pi)如何解释这些响应。可能的情况有如下5种。

情况1:Pi从所有Pj处接收″vote-abort″消息。这意味着没有一个其他参与者已经做出肯定选举,它们已经选择单边夭折事务。在这些条件下,Pi可以继续按夭折处理事务。

情况2:Pi从某个Pj处接收″vote-abort″消息,但是某些其他参与者表示已经处于READY状态。此时,Pi仍然可以继续往前走,并夭折该事务,因为按照全局提交规则,事务已不能提交而只能夭折。

情况3:Pi从所有Pj处接收到通知,它们处于READY状态。此时,没有一个参与者知道事务的命运,以便正常终止它。

情况4:Pi从所有Pj处接收到″global-abort″或″global-commit″消息。此时,所有其他参与者已经接收到协调者的决策。因此,Pi仍然可以继续往前走,按照它从其他参与者接收到的消息终止该事务。

情况5:Pi从某个Pj处接收到″global-abort″或″global-commit″消息。此时,其他参与者处于READY状态。这表示某些节点已经接收到协调者的决策,而其他参与者仍在等待这个消息。此时按情况4处理Pi

这5种情况涵盖了所有需要处理的终止协议。(www.chuimin.cn)

注意,在情况3时,参与者的处理处于阻塞状态,因为它们无法终止事务。有些情况下可以找到克服这种阻塞的方法。如果在终止所有参与者期间认识到只是协调者节点出现故障,那么可以选举一个新的协调者,并重新启动提交过程。选举协调者的方法有很多。可以将节点安排成一个全序,一个一个地选举;或者建立一个参与者的选举程序。但是,如果有一个参与者和协调者同时出现故障,则上述情况就不工作了。此时有可能这个出现故障的参与者已经接收到了协调者做出的决策,已经遵循此决策终止了事务。其他参与者不知道这个决策,因此,如果选举新决策者和继续处理,那么会存在造成做出矛盾决策的危险。显然不能设计出一个既是2PC又不能保证无阻塞的终止协议。因此,2PC是一个有阻塞的协议。

算法10.3 2PC(协调者)终止。

2.恢复协议

2PC协议可以处理操作节点出现故障的问题。现在我们要关注协调者或参与者在出现故障时和重启动后如何恢复这些节点状态的问题和相关的协议。

我们以图10.13为例,并假设:①在日志中写一条记录和发送一条消息是一个原子操作;②状态的转换发生在传输了相应消息之后。例如,如果一个协调者处于WAIT状态,则表示它已经成功地在日志里写入了begin-commit记录并且成功地发送了prepare命令。注意,我们说的是成功地发送,不是说成功地传输。发送以后,如果参与者没收到,则是通信故障的问题。这个原子性的前提在实现时并不合理,但这里可以简化我们的讨论。

1)协调者节点故障

当协调者节点出现故障时,可能会发生如下情况。

(1)协调者在INITIAL状态出现故障。因为此时协调者在启动提交过程前,所以采取的措施是在恢复时重新启动提交过程。

(2)协调者在WAIT状态出现故障。此时,协调者已经发送了prepare命令。常言道,开弓没有回头箭,恢复时,协调者为这个事务重新启动commit过程,重新向每个参与者发送″prepare″消息。

(3)协调者在COMMIT或ABORT状态出现故障。此时协调者已经通知参与者其决定是提交或夭折,终止事务。所以一旦恢复,若协调者已经收到各个参与者的答复消息,则什么也不需要做。否则,执行终止协议。

2)参与者节点故障

当参与者节点出现故障时,可能会发生如下情况。

(1)参与者在INITIAL状态时出现故障。恢复时,参与者应当单边终止事务。因为此时对于该事务而言,协调者处于INITIAL或WAIT状态。如果协调者处于INITIAL状态,则它发送″prepare″消息,转成WAIT状态。由于有参与者节点故障,协调者收不到参与者决定的消息,超时,因此做出了全局夭折的决定。

(2)参与者在READY状态时出现故障。此时在故障前协调者已经通知了出现故障的节点,其决定是什么。所以恢复时,故障节点的参与者可以按READY状态下的超时来处理,采用终止协议来处理这个不完整的事务。

(3)参与者在ABORT或COMMIT状态时出现故障。这些状态代表了终止条件,所以恢复时,参与者无需采取特殊行动。

除此之外,还有一些其他情况需要指出。

(1)协调者将begin-commit记录写入日志后,但在发送prepare命令前出现故障。协调者就像在WAIT状态那样(与协调者节点故障情况(2)类似),在恢复时发送prepare命令。

(2)参与者在往日志里写入ready记录后,但尚未发送″vote-commit″消息前出现故障。此时参与者的反应与参与者节点故障情况(2)类似。

(3)参与者在往日志里写入abort记录后,但尚未发送″vote-abort″消息前出现故障。此时参与者不需要作什么动作,因为此时协调者处于WAIT状态,会发现超时。协调者会根据终止协议发出全局夭折命令。

(4)协调者在将最后决定(commit或abort)记录写入日志后,但在向参与者发送globalcommit或global-abort命令前出现故障。此时协调者的处理如其前面的情况3,参与者的处理如READY状态下的超时。

(5)参与者在往日志里写入commit或abort记录后,但尚未发送″acknowledgment″消息前出现故障。参与者的反应如其前面的情况3。协调者则按在状态COMMIT或ABORT时的超时处理。