本发明涉及一种用于在多个时间间隔期间在第一存储器中跟踪对象的方法和装置。本发明还涉及一种存储程序代码的计算机可读存储介质,该程序代码用于执行一种用于在多个时间间隔期间在第一存储器中跟踪对象的方法。
背景技术:
硬件的发展已使得许多重要的高更新速率事务应用能够完全在存储器中执行。此类应用包括事件处理系统、电子交易系统、多人游戏、电信领域服务控制应用、测量系统、科学模拟和许多其它应用。
这些应用中更新事务的耐久性通常由周期性检查点检查进程和逻辑重做日志提供,周期性检查点查检进程将一致存储器状态刷新到永久性存储,逻辑重做日志记录连续检查点之间的所有修改请求。在系统故障的情况下,恢复进程使用最新的永久性检查点来初始化存储器状态,并使用重放程序来重放重做日志以重新创建故障发生时间之前的点时的应用状态。
在此类高更新速率系统中,检查点效率和不妨碍正常应用操作是至关重要的。为了不妨碍高更新速率并实现频繁检查点检查,检查点检查进程必须开销非常低并且效率高。频繁的检查点检查反过来减小了重做日志大小并缩短了与其相关联的恢复时间时日志重放持续时间。由于检查点反复运行,仅检测和持久化自上一检查点发生变化的对象的增量检查点检查方法受到高度重视。
典型的检查点检查方法利用拍摄各种粒度的快照的特定方法,因此检查点管理的逻辑与拍摄快照的逻辑是紧密结合的。
例如,更新时复制方法将应用对象分组成块,并且每当对象在时间间隔期间被改变时将每个块复制到影子状态。由于更新线程并发更新应用状态,因此更新线程需要获取更新线程引用的块上的锁。通过改变存储器块的大小,更新时复制在复制开销与锁定开销之间进行均衡。更新时复制方法导致较大开销和显著延迟,使得它不适合用于高速更新。另外,在新检查点检查开始时,这种方法会静默更新以重置更新标记和循环影子对象的内存。
免等待曲折方法(wait-freezigzagmethod)为每个元组预分配复本空间,并标记哪一副本保存元组的快照。在新的检查点开始前,应用需要静默其更新以便一致地标记每个元组的副本之一来用作下一快照元组。
另一种流行的技术是批量复制,通过该技术整个应用状态被复制以用于检查点检查。批量复制更新导致高延迟,并且它并不适用于其中例如复杂对象结构要求“深度复制”的某些应用。
实验已经表明,没有一种已知的快照方法适合维持更新速率的整个动态范围。所有的上述方法都涉及上述特定快照拍摄方法,因而具有高复杂性。由于这种复杂性,变化集的定义和高效计算可能代价高昂。另外,现有技术通常导致特定应用锁定或更新静默的强制执行。
技术实现要素:
本发明的目标在于提供一种克服一个或多个现有技术的上述问题的用于在多个时间间隔期间在第一存储器中跟踪对象的方法和装置。本发明的另一目标在于提供一种存储用于执行这种方法的程序代码的计算机可读存储介质。
本发明的第一方面提供一种用于在多个时间间隔期间在第一存储器中跟踪对象的方法,所述对象包括一个或多个状态变量,其中所述方法包括以下步骤:
一个或多个更新线程更新已变化对象的状态变量,所述已变化对象是当前时间间隔期间已变化的对象,
当新的时间间隔开始时,一个或多个测试线程为每个对象创建捕获所述对象的状态并且对应于所述对象的影子对象,
所述一个或多个测试线程评估所述影子对象的状态变量以确定包括非复制变化的一个或多个非复制影子对象,
所述一个或多个测试线程将所述一个或多个非复制影子对象复制到第二存储器,
所述一个或多个测试线程确定所述复制所述一个或多个非复制影子对象的步骤是否成功,以及
所述一个或多个测试线程更新对应于复制成功的所述一个或多个非复制影子对象的对应对象的状态变量,
其中所述状态变量的后续比特对应于后续时间间隔,并且其中所述一个或多个更新线程和所述一个或多个测试线程对所述状态变量的不相交比特集进行操作。
创建对应于所述对象并且捕获所述对象的所述状态的影子对象可以例如通过简单地复制所述对象来实现。
将非复制影子对象复制到第二存储器还包括其中所述非复制影子对象的状态被持久化在所述第二存储器上的情况。
根据本发明的第一方面,一个或多个更新线程可以更新对象,例如应用的存储器驻留对象,并将更新后对象标记为当前时间间隔期间发生变化,而另一组线程,即所述一个或多个测试线程,创建影子对象并测试所述影子对象以得到任何先前变化。所述一个或多个更新线程和所述一个或多个测试线程对所述变化状态变量中的不相交比特集进行操作,并对其进行相应地标记。
每个所述对象具有指示所述对象是否被改变的状态变量。所述一个或多个更新线程和所述一个或多个测试线程访问所述状态变量。具体而言,所述一个或多个更新线程可以访问所述对象本身的所述状态变量,而所述一个或多个测试线程访问所述影子对象的所述状态变量。
所述方法确保所述一个或多个更新线程和所述一个或多个测试线程对所述状态变量的不相交比特集进行操作。因此,避免了其中结果不确定地取决于所涉及的线程之间的定时的竞争情况。
在根据所述第一方面的所述方法的第一实施方式中,创建所述影子对象包括派生子进程的步骤。
派生子进程,例如使用fork()系统调用,创建其地址空间用作所述快照的子进程。因此,创建了快照一致的状态。父进程的数据(例如,包括所述对象)可以在每当数据变化发生时根据os页面粒度以动态方式(写入时复制)懒惰地“复制”。创建所述影子对象的所述基于派生的方法例示了快照与变化集计算之间的清晰的逻辑分离。
根据所述第一方面的所述方法的第二实施方式中,所述方法是用于创建所述对象的永久性副本的检查点检查方法,其中所述一个或多个非复制影子对象被复制到永久性存储,特别是硬盘。这对于确保对所述对象的改变不会例如由于电力故障而丢失是尤其相关的,电力故障可能影响所述第一存储器但不会影响所述永久性存储。
因此,本发明的所述方法可以在增量的、快照一致的检查点过程的上下文中使用,所述增量的、快照一致的检查点过程在通常设置中可以例如定义如下:
存在连续地修改一组存储器驻留对象的一组更新线程。
在检查点时,拍摄所述应用存储器状态的一致快照,从而捕获不可变对象内的一致的存储器状态,称为影子对象。所述影子对象的被所述更新线程相对于上一(成功)检查点修改的被称为已变化集的子集被刷新到所述磁盘。
如果所述前一检查点不成功,用于所述当前检查点和所述前一检查点的变化集被合并,即刷新到磁盘的所述变化集被计算为所述当前变化集与所述前一变化集的并集。
在根据所述第一方面的所述方法的第三实施方式中,所述方法包括当检查点被请求时开始新的时间间隔的步骤。因此,时间间隔的顺序对应于检查点的顺序。
在根据所述第一方面的所述方法的第四实施方式中,所述一个或多个更新线程使用指示当前时间间隔的标记掩模来更新所述一个或多个已变化对象的所述状态变量,和/或所述一个或多个测试线程使用指示其间成功复制所述一个或多个非复制影子对象的先前时间间隔的测试掩模来更新所述状态变量。
任何线程在时间间隔中对任何对象的更新可以由所述一个或多个更新线程进行标记,所述一个或多个更新线程将所述对象的状态变量设置为所述状态变量与所述标记掩模在该时间间隔时的特定状态的按位或。测试对象是否被改变可以通过将所述时间间隔的所述特定测试掩模与所述状态变量的按位与跟零进行比较来执行。
所述测试掩模和所述标记掩模指示不同的时间间隔。因此,使用这些掩模来访问所述对象的状态变量(以及所述对应影子对象的所述状态变量)是确保所述一个或多个更新线程和所述一个或多个测试线程总是对所述各状态变量的不相交比特集进行操作的一种特定方式。如上所述,这例如对于避免所述方法的竞争情况和不确定表现是重要的。
在根据所述第一方面的第四实施方式的所述方法的第五实施方式中,更新所述标记掩膜包括自动旋转其比特值,并且更新所述对象的所述状态变量包括分配所述对象的与所述标记掩模或组合的所述状态变量。因此,所述标记掩模可以通过将其左旋转一比特而前进,从而自动开始新的时间间隔。这是更新所述标记掩模和使用所述标记掩模来访问所述状态变量的特别高效的方式。
在本发明实施例中,如果所述上一检查点是成功的,那么所述测试掩模在当前时间间隔期间保持所述标记掩模自所述上一时间间隔的值。因此,在所述检查点检查间隔期间,新变化的对象被所述新标记掩模标记,而使用所述前一标记掩模对它们的影子对象进行测试以得到变化。在所述时间间隔结束时,所述测试掩模被设置为所述标记掩膜的值。此外,所述状态变量中表示所述检测到的对象的所述变化的比特被重置为零。如果所述检查点由于某种原因失败,所述测试掩模可以设置为自身与所述标记掩膜的值的按位或,从而实现在下一时间间隔中对所述当前已变化和先前已变化的对象的测试。
在根据所述第一方面的所述方法的第六实施方式中,评估所述状态变量包括自动评估所述测试掩模与所述状态变量的按位与组合。这是使用所述测试掩模评估所述状态变量的特别高效的方式。
在根据所述第一方面的所述方法的第七实施方式中,当确定所有对象已被成功复制时,所述测试掩模被设置所述标记掩模的值,和/或当确定所述已变化对象中的至少一个的复制失败时,所述测试掩模被设置为与所述测试掩模或组合的所述标记掩模。
在根据所述第一方面的所述方法的第八实施方式中,所述测试掩模和/或所述标记掩模被初始化为1。这提供了所述方法的明确定义的起点。
如果存在比所述状态变量可以存储的更多的检查点和时间间隔,所述方法可以使用环绕,即,它再次从所述状态变量和所述掩模的第一比特开始。例如,如果所述状态变量和所述测试掩模以及所述标记掩模是32比特变量,那么这些32比特可以对应于第一32个时间间隔,并相应地对应于第一32个检查点,如果所述方法是检查点检查方法的话。对于第33个检查点,第一比特可以再次使用。换句话说,编号为n+1(其中n是所述标记掩模和/或所述状态变量的按比特计大小)的时间间隔再次对应于所述标记掩模和所述状态变量的第一比特。
如果对于多于n个先前间隔存在未复制变化,这可能导致所述方法“遗忘”一些未复制变化。因此,所述第一方面的所述方法可以包括验证对于多于n个先前间隔是否存在未复制变化的步骤,其中n是所述状态变量、所述标记掩模和/或所述测试掩模的比特数量。在这种情况下,所述方法可以包括生成可以通知操作者所述检查点检查不成功的警报信号例如视觉和/或听觉信号的步骤。所述方法也可以随后自动改变为一种不同的生成一致检查点的方法。例如,由于不再可能跟踪新变化,作为一种应急措施,所述方法可以恢复为针对所述检查点中的每个检查点创建所有对象的副本。这是耗费资源的,但与不存储已变化对象相比可能是优选的。
在根据所述第一方面的所述方法的第九实施方式中,所述标记掩模和/或所述测试掩模是全局变量和/或所述对象的所述状态变量是所述对象的局部变量。通过使用局部变量,可以确保只有所述对象本身可以访问它们的状态变量,即,可以防止对它们的状态变量的未授权访问。
在根据所述第一方面的所述方法的第十实施方式中,对象的状态变量和对应影子对象的状态变量是共用的。这允许更为高效的实施方式,因为可以避免所述状态变量的不必要的复制。
在根据所述第一方面的所述方法的第十一实施方式中,更新所述对应对象的所述状态变量包括将所述状态变量中的一个或多个设置为所述状态变量中的所述一个或多个的按位异或组合以及所述状态变量与所述测试掩模的所述按位与组合。
在根据所述第一方面的所述方法的第十二实施方式中,所述对象的所述状态变量由所述对象进行管理。这可以适用于所述(初始)对象以及对应于所述对象的所述影子对象。这种实现确保了对所述状态变量的未授权访问被防止。
根据本发明的第二方面,提供了一种用于在多个时间间隔期间在第一存储器中跟踪对象的装置,其中所述装置包括所述第一存储器、第二存储器、第一处理核心和第二处理核心,其中
所述第一处理核心用于执行一个或多个更新线程,所述一个或多个更新线程更新已变化对象的状态变量,所述已变化对象是在当前时间间隔期间已变化的对象,并且
所述第二处理核心用于执行执行以下步骤的一个或多个测试线程:
当新的时间间隔开始时,为每个对象创建捕获所述对象的状态并且对应于所述对象的影子对象,
评估所述影子对象的状态变量以确定包括非复制变化的一个或多个非复制影子对象,
将所述一个或多个非复制影子对象复制到第二存储器,
确定复制所述一个或多个非复制影子对象是否成功,以及
更新对应于复制成功的所述一个或多个非复制影子对象的对应对象的状态变量,
其中所述状态变量的后续比特对应于后续时间间隔,并且其中所述一个或多个更新线程和所述一个或多个测试线程对所述状态变量的不相交比特集进行操作。具体而言,所述装置用于执行所述第一方面或所述第一方面的所述实施方式之一的所述方法。也就是说,所述装置用于包括必要装置以执行所述第一方面或所述第一方面的所述实施方式之一的所述方法。
本发明的第三方面提供一种存储程序代码的计算机可读存储介质,所述程序代码包括用于执行所述第一方面或所述第一方面的所述实施方式之一的所述方法的指令。
如上所述,本发明实施例可以强加所述拍摄快照的方法与所述变化集计算方法之间的关注点的明确分离。可以消除暂停更新线程的需要。所述一个或多个更新线程的标记开销可以是轻量的并且无需等待,因为没有使用锁。在一些实施例中,所有对象的变化状态变量利用按位运算自动地更新。在实施例中,变化可以跨越连续检查点进行跟踪,下一检查点检查开始是自动且瞬时的。所述方法的正确性,包括避免竞争情况,包含在其设计之中。最后,以上特征可以意味着幂等检查点:尽管有故障,但所有数据对象变化都被持久化。
附图说明
为了更清楚地说明本发明实施例中的技术特征,下面将对实施例描述中所需要使用的附图作简单地介绍。下面描述中的附图仅仅是本发明的一些实施例,这些实施例在不违背本发明如权力要求书中所定义的保护范围的情况下,可以进行修改。
图1示出根据本发明的将多个时间间隔期间的对象变化持久化的方法的示意图,
图2a示出本发明实施例的由一个或多个测试线程执行的方法步骤的流程图,以及
图2b示出本发明实施例的由一个或多个更新线程执行的方法步骤的流程图。
具体实施方式
图1提供检查点方法的图示,其中在三个时间间隔11、12、13上跟踪四个对象31、32、33和34。第一时间间隔11先于第一检查点21。第二和第三间隔12、13被定义为第一、第二和第三检查点21、22、23之间的间隔。第四时间间隔14在第三检查点24之后。第一和第四对象31、34在第一间隔11中被改变(利用参考编号41、42指示)。第四对象在第二间隔12中再次被改变43。在第三间隔13中,第二和第三对象32、33被改变44、45。
在第一时间间隔11(其在第一检查点21时结束)中,变化集由第一和第四对象31、34,即在第一检查点21之前被修改的对象,组成。在第一检查点时,即当第二时间间隔开始时,对象被标记为相对于第一检查点发生变化。由第一和第四对象31、34组成的变化集在第二时间间隔期间被成功持久化。
在第三时间间隔开始时,由第四对象组成的变化集被检测到,即检测到obj4已在第一和第二检查点21、22之间被修改过。尝试将第二变化集刷新到磁盘。这导致(由于未知原因)磁盘写入失败。在第四时间间隔14中,计算所得变化集由第二、第三和第四对象32、33、34组成。这一变化集来自在第三时间间隔13中未能持久化的第四对象34与由被检测为在第三时间间隔13中发生变化的第二和第三对象32、33组成的变化集的并集。
一般而言,通过应用概念“关注点分离”,只要创建了对象的状态的一致的不可变副本,快照捕捉的方法就不必为检查点检查方法的关注点。
在新的检查点开始时,需要保留对象的相对于上一检查点已变化的状态变量,连同将所有对象标记为在即将来临的检查点的持续时间期间未变化,所有这些在存在多个并行更新时进行。
图2a是测试线程执行的方法步骤的流程图。图2a中所示的实施例是基于存储器中数据库fork()的、快照一致的且增量的检查点方法的示例。
下文中,change_mark_mask是标记掩膜的示例,change_test_mask是测试掩模的示例,change_status、change_status_i和change_status_j是对象和/或影子对象的状态变量的示例。
存在与它们之一在数据库中运行的若干线程,称为测试线程,以管理增量检查点的执行。测试线程在步骤s10中旋转change_mark_mask,在s20中派生子进程,从而创建与对应于父线程的对象的影子对象一致的快照,并且随后在步骤s30中父测试线程等待子进程报告其退出状态。
在步骤s25中,控制流程取决于是父进程还是子进程被执行。
在步骤s50中,子进程在应用状态测试中遍历所有影子对象,如果它们已使用change_test_mask被改变的话。这是通过对change_test_mask与对象的change_status成员变量进行和运算完成的。如果结果为非零,则意味着检测到变化,并且随后该影子对象被持久化到文件系统作为新文件,而将现存文件复制到备份副本(步骤s60)。如果所有的新文件被安全地存储在文件系统中,那么检查点被认为是成功的。否则,如果任何新文件未能被存储在文件系统中,所有的备份副本被恢复为当前检查点文件(步骤s80)。在这种情况下,子进程退出并报告失败作为其退出状态。
当子进程退出时,父进程醒来(步骤s30)并测试子进程的退出状态。如果退出状态是成功的,父进程清除change_status中表示已变化对象的变化的所有比特(步骤s100)。这是为了确保change_mark_mask外包时的干净状态。外包可以例如在时间间隔的数量大于标识变量和/或标记掩模的大小(以比特计)时发生。
然后,在步骤s110中,父进程通过使用change_mark_mask的值来设置change_test_mask。正常情况下,在成功的检查点之后,change_test_mask中仅剩余一个比特。如果检查点不成功,则对change_test_mask与change_mark_mask进行或运算,从而将当前变化集与前一变化集结合起来。这发生在步骤s90中。change_test_mask中的多个“1”指示一个或多个连续检查点已失败。最后,测试线程开始等待下一检查点请求。
下文中,该方法的执行利用状态变量change_status_i和change_status_j、测试掩模change_test_mask和标记掩模change_mark_mask的特定示例值进行说明。在该示例中,展示了所涉及的状态变量和掩模的值在紧跟系统的初始化的两个时间间隔期间如何演变。本示例跟随两个对象的变化状态:oi和oj。还假设第一检查点操作失败,这导致需要最终对在两个时间间隔期间变化的数据对象进行检查点检查。第二检查点操作成功。出于示例的简明起见,使用4比特值。
系统初始化时的初始值是:
change_test_mask=0001
change_mark_mask=0001
假设存在两个数据对象oi和oj。它们各自的状态变量最初具有零值:
change_status_i=0000
change_status_j=0000
假设对象oi在第一检查点请求发出之前被更新。这导致以以下方式设置其change_status:
change_status_i←change_status_iorchange_mark_mask
change_status_i=0000
or
change_mark_mask=0001
---------------------------------------
change_status_i=0001
在步骤s10中,在新检查点请求时,主测试线程被激活,并且change_mark_mask被左旋转并变为[0010]。在步骤s20中,测试线程派生子进程,并且在父进程中,等待子进程退出(步骤s30)。
在步骤s40中,在父进程中,对象oj被更新线程更新。首先,检查变化还没有被标记。这是为了防止不必要的写入。
change_status_j=0000
and
change_mark_mask=0010
--------------------------------------
result=0000
由于结果为零(未记录到变化),针对对象oj记录变化:
change_status_j=0000
or
change_mark_mask=0010
---------------------------------------
change_status_j=0010
注意,这一变化在子(派生)进程中是不可见的。与此同时,在子进程中,发生检查点处理。在步骤s50中,利用change_test_mask对所有数据对象的change_status成员进行测试(使用and)。如果结果为非零,则给定对象被持久化。
change_status_i=0001
and
change_test_mask=0001
--------------------------------------
result=0001
change_status_j=0000(在子进程中可见的值)
and
change_test_mask=0001
--------------------------------------
result=0000
变化测试结果为非零的对象被持久化。在这种情况下,对象oi在该时间间隔期间被持久化。
在步骤s60中,在永久性存储中创建现有永久性对象oi的备份副本。然后,对象oi本身被持久化。
此时,假设测试线程的子进程已经由于某种原因如i/o错误而失败。对象oi的备份副本被恢复来替代被持久化的对象oi,以回复到检查点开始之前的状态(步骤s80)。然后,测试线程的子进程以“失败”退出状态退出。
测试主线程测试子进程的退出状态,并且因为子进程“失败”,它使用change_mark_maskorchange_test_mask的结果替代change_test_mask(步骤s90)。
change_test_mask←change_mark_maskorchange_test_mask
change_mark_mask=0010
or
change_test_mask=0001
-----------------------------------------
change_test_mask=0011
在下一检查点请求时,新的时间间隔开始。change_mark_mask被测试线程左旋转并变为[0100](步骤s10)。
在步骤s20中,测试线程派生子进程,并且在父进程(在步骤s25中确定)中,等待子进程退出(步骤s30)。
假设对象oj此时在更新线程中被更新。对应的变化比特被设置。
change_status_j=0010
or
change_mark_mask=0100
---------------------------------------
change_status_j=0110
注意:这一变化仅在父进程中可见。
与此同时,在子进程中,发生检查点处理。在步骤s50中,利用change_test_mask对所有数据对象的change_status成员进行测试(使用and)。如果结果为非零,则给定对象被持久化。
change_status_i=0001
and
change_test_mask=0011
--------------------------------------
result=0001
change_status_j=0010(在子进程中可见的值)
and
change_test_mask=0011
--------------------------------------
result=0010
变化测试结果为非零的对象被持久化。在这种情况下,对象oi和oj均在该时间间隔期间被持久化。
在步骤s60中,首先,在永久性存储中创建现有对象oi和oj的备份副本。然后,对象oi和oj被持久化。
这一次,检查点被成功执行。oi和oj的备份副本被丢弃(从永久性存储移除)(步骤s70)。然后,测试线程的子进程以“成功”退出状态退出。
图2b图示出本发明实施例的由一个或多个更新线程执行的方法步骤。更新线程使用change_mark_mask中的值来测试对象的change_status是否已被更新。这是为了在对象的change_status已被该线程或同时修改change_status的其它并发线程所更新的情况下不必要的缓存线无效和更新序列化。如果change_status尚未更新(在步骤s5中确定),那么它在步骤s40中被更新。
上文所有描述仅仅为本发明的实施方式,本发明所保护的范围并不仅限于此。本领域的技术人员可以容易地得到任何变体或替代。因此,本发明的保护范围应依据所附权利要求的保护范围。