浅谈事务管理器的事务恢复处理方案
扫描二维码
随时随地手机看文章
随来社会的进步,计算机的广泛应用,很多事务处理过程中事务的恢复工作一般依赖于计算机数据库管理系统,而事务管理器必须做好分布式事务处理的事务恢复处理。这需要做好二个阶段的工作:在正常的事务处理过程中,交易中间件在稳定存储器中完整记录事务恢复时的必要信息;在事务的恢复阶段,恢复系统根据稳定存储器中记录的事务相关信息恢复事务。本文就对该系统进行讲解。
在OMG组织的OTS(对象事务服务)中规定了一套事务失败恢复的模型。该模型是基于假定回滚的策略恢复失败的事务。假定回滚是事务二阶段提交协议的一种效率优化策略,事务发起者在决定提交之前和资源在准备好之前都不用写任何日志。这样在失败发生后重新启动时,所有未记录日志的事务都认为已经做过回滚操作。
ACID,指数据库事务正确执行的四个基本要素的缩写。包含:原子性(Atomicity)、一致性(CONsiSTency)、隔离性(IsolATIon)、持久性(Durability)。一个支持事务(TransacTIon)的数据库系统,必需要具有这四种特性,否则在事务过程(Transaction processing)当中无法保证数据的正确性,交易过程极可能达不到交易方的要求。
本文分析了OTS的事务失败模型的恢复机制,用Java语言实现了交易中间件的事务恢复子系统,从而保证了分布式交易处理的完整性和一致性。
1 OTS中的事务失败模型和恢复机制
1.1 事务的失败模型
事务服务在应用、系统或通信失败时,要提供事务的原子性结果。下面描述失败发生时各应用实体的行为。
(1)事务创建者
局部失败:在事务创建者发出提交命令之前的失败将引起事务回滚。在事务创建者发出提交命令之后而在事务结果报告之前的失败,依赖于时机导致提交或回滚。这种情况下事务的完成情况与事务创建者的失败无关。
外部失败:任何在事务创建者发出提交命令之前的外部失败,都将引起事务的回滚。在事务创建者发出提交命令之后而在事务结果报告之前的失败,意味客户端可能不会通知事务的结果,这依赖于失败的特征和提交命令是否使用report_heuristics选项。但这也不是可靠的方法,因为可能得到事务不存在的结果。
(2)事务服务器
局部失败:事务服务器失败后,事务服务如果实现可选的检查方法,将引起事务的回滚。如果没有实现可选的检查方法,事务是否回滚取决于事务的提交命令是否发出。当未检查的客户端在收到所有服务器的应答之前发出提交命令时就是这种情况。
外部失败:任何在事务服务器执行过程发生的外部失败都将引起事务的回滚。事务对象的方法执行时发生失败,将不会影响方法的执行。方法将会正常结束,返回结果到客户端。最后事务回滚异常返回到发出提交命令的客户端。
(3)恢复服务器
可恢复服务器在失败发生时的行为决定于Coordinator与可恢复服务器的资源对象之间的二阶段提交协议。
1.2 事务失败后的继续完成
通常,完成方法是在失败发生点继续完成事务。这意味着Coordinator常常有责任向注册的资源发送提交命令。某些失败情况下也需要资源初始化恢复程序。
资源代表与某一事务关联的可恢复数据的集合。当失败恢复时,已经准备好的资源使用RecoveryCoordinator对象的reply_completion方法确定事务的结果和完成事务。
根Coordinator在日志记录决定提交前的失败可能是单方面的回滚事务。如果所有资源都准备好,需要初始化的恢复过程如下:若根Coordinator的结果是提交,则发出提交命令继续完成协议;若根Coordinator的结果是回滚,则发出回滚命令继续完成协议。
2 事务的恢复处理
事务恢复,就是能够在容错的方式下继续完成事务。通过日志的记录信息,在恢复过程中使用这些有用的信息恢复事务。
事务恢复的二个阶段是:①正常操作时,在事务处理过程中存储必要的信息到日志顺序文件,后台进程对已完成的顺序文件做归档操作。②恢复过程中,通过归档文件和日志文件的信息恢复事务。
2.1 事务的正常阶段
(1)事务的状态及保存点
在OTS中,事务的惟一标识是事务标识。事务标识由三个字段的数据结构表示:全局事务标识,用GtxID表示;分支事务标识,用BqualID表示;事务的格式标识,用FORMATID表示。由以上三个字段组成的事务标识可以惟一标识任何范围内分布式计算环境中的一个事务。
事务在其整个生命周期中存在以下的状态:活动事务,正在准备的事务,准备好的事务,正在提交的事务,已完成提交的事务,正在回滚的事务,已完成回滚的事务,标记为回滚的事务,出现启发式异常的事务。
根据OTS规范的事务失败假定回滚策略,所有在事务失败时没有决定提交或回滚的事务,在恢复处理过程中都可以忽略。为了简化事务失败恢复的操作,提高交易中间件的事务处理能力,选取事务处理过程中的以下几个关键点做为事务的保存点。在事务的生命周期中遇到事务的保存点,就必须在事务的日志文件中记录下事务的相关信息程中使用。事务的保存点如下:PREPARED:二阶段提交事务的准备阶段正常完成后,事务管理器向各个资源发出提交命令之前;COMMIteD:事务提交正常完成之后;ROLLBACKED:事务回滚正常完成之后;UNKNOWN:事务出现HEURISTIC异常。在事务的保存点除了记录事务的状态信息以外,还需要记录事务的标识信息。可以用三个值分别记录事务的全局事务标识、分支事务标识及格式标识。
(2)日志文件的设计
日志文件以行数据作为结构单元。一行数据包括以下几列:第一列值表示全局事务标识;第二列值表示分支事务标识(BqualID);第三列值表示格式标识;第四列值表示事务保存点的状态;第五列值是行结束符。每个文件的行数可以配置为一个定值ROWMAX,写满了一个日志文件后,便可以开始写下一个顺序文件。
事务的处理进程在事务的保存点根据事务的信息添加一行记录。每个日志文件长度达到ROWMAX行后,做一个标记,创建一个新的日志顺序文件,并刷新事务进程的写缓冲区,开始在新的日志文件中记录。
后台单独有一个线程对已写满的日志文件做归档操作。归档文件和日志文件的结构是相同的,所有的日志文件归档后保存到一个归档文件中。日志文件归档完成后就删除该日志文件或做归档完成标记。
事务写日志的流程图如图1所示。
(3)其他优化
为了提高写日志的效率、减少系统资源的开销,事务的状态值可以用一个字节表示,事务的标识可以用定长个数的字节表示。
日志文件的同步写操作在成千上万的事务并发处理过程中,可能成为事务处理器的瓶颈。因此有必要同时开辟若干个写缓冲区和若干个日志文件供不同的事务并发写日志。
2.2 事务的恢复阶段
(1)恢复方式
事务的恢复有二种可行的方式:
①事务管理器恢复并发送结果到资源。资源不用主动参与恢复过程,只是正常的提交或回滚命令被触发。
②资源没有发现事务结果传递过来,就发请求到事务管理器。事务管理器恢复RecoveryCoordinator对象,资源通过该对象的replay_completion()方法请求获得事务结果,如果不能获得结果信息,则回滚事务,否则按获得的结果完成事务。
为了事务的完整性,OTS在恢复时,既要恢复RecoveryCoordinator对象,又要根据日志中事务的状态向注册的资源发送commit()或rollback()命令。
(3)事务恢复
事务恢复根据以下规则进行:所有活动的事务都必须恢复,所有已经准备提交的事务都提交,所有已经准备回滚的事务都回滚,所有状态未知的事务都回滚。
事务发生失败后,在交易中间件重启时要做恢复操作。首先读取失败时日志目录下所有未来得及归档的日志文件,再读取归档文件中的内容。恢复过程如图2所示。
读取日志文件和归档文件后,要根据以下算法筛选出失败时没有完成的事务。下面是筛选算法的Java原语:
if(Log.decision==COMMITED || Log.decision
==ROLLEDBACK){
//忽略这些事务
}
if(Log.decision==UNKNOWN)
//日志文件中存在需要重新提交的事务,重启Coordinator,
//发出提交命令
//重启该事务
Restart(tx)
//回滚事务
tx.rollback();
}
if(Log.decision==DECISION_TO_ROLLBACK)
//日志文件中存在需要回滚的事务,重启Coordinator,发出
//回滚命令
//重启该事务
Restart(tx)
//回滚事务
tx.rollback();
if(Log.decision==DECISION_TO_COMMIT)
//日志文件中存在需要回滚的事务,重启Coordinator,发出
//回滚命令
//重启该事务
Restart(tx)
//提交事务
tx.commit();
2.3 系统的模型结构
(1)系统模型主要由四个对象组成:①日志文件操作对象。该对象保证事务管理器所有进程共享写日志文件和写缓冲区。通过该对象,格式化日志的行数据并写入日志文件,读出日志文件的数据并解析行数据,删除满足条件的行数据等。②日志管理对象。③日志归档对象。后台线程定时归档日志文件。从日志文件和归档文件中筛选出未完成的事务记录,更新到归档文件中。④日志恢复对象。事务管理器重启时,读取归档文件和未来得及归档的日志文件的内容,恢复日志中未完成的事务。
(2)模型结构
系统的模型结构如图3所示。
3 结 论
依据OMG组织的OTS规范,本文分析了分布式事务的恢复处理过程,并实现了该系统在交易中间件的应用。它不仅适合于一般的事务失败恢复,而且保证了事务失败情况下的事务完整性和一致性。在操作日志文件时利用格式化的行数据的优越性,可以减少事务处理过程中持久化事务相关信息占用的系统资源,提高交易中间件事务处理的效率。由于事务失败的绝对性存在,建立事务失败的分布式组件模型,明确各组件在事务恢复过程的职责,协调好各组件参与事务的恢复处理。