用增量分页器来管理状态
背景
执行数据库事务时的一个关键问题是数据库完整性。为保持数据库完整,重要的是确保事务遵守诸如原子性和隔离等要求。原子性要求命令要么执行一事务的全部任务,要么不执行任何任务,因而不完整的事务不会被应用于数据库。隔离要求规定事务与其它事务分开处理,因而没有事务访问或干涉另一事务的中间状态。遵守原子性和隔离要求防止事务彼此破坏并破坏作为整体的数据库。
在联网系统中,许多用户和许多应用程序可能并发地试图对同一数据执行事务。即使在单机系统中,多个应用程序也可能用彼此竞争的每一应用程序的多个处理线程来并发地试图对同一数据执行事务。由于难以预见,更不用说避免在事务中可能向数据库应用冲突或不一致的改变的所有情形,因此维持数据库完整性是一项重大的挑战。
保持数据库完整性的一种方式是对当前事务使用的数据库的一部分加上锁。对数据库的一部分加上锁防止其它事务在当前事务完成之前读取或盖写该数据。防止其它事务从数据库的该部分读取确保其它事务将不会基于当前事务可能改变的值而得出结果。因此,防止其它事务盖写数据库的该部分确保其它事务不会影响当前事务。
然而,尽管对数据库的一部分加上锁有可能有助于保持数据完整性,但是它也会导致补偿成本。对多个事务试图访问的数据库的一部分加上锁可造成事务的大量积累。部分或全部等待的事务可能不会对数据库的当前状态作出任何改变,或可能不会对当前事务所使用的特定值进行读取、写入或改变。然而,对数据库的该部分加上锁将保持数据库的完整性,即使它使得对数据库的访问变慢。
一种形式的锁是租用。正如在公寓、建筑物、汽车和设备租用的情况中一样,租用是一段有限时间内的独占授权。由此,当一事务被授予对所选数据的租用时,向该事务提供在一段有限时间内对所选数据的独占访问。通过将对该数据的独占访问限于一段时间,如果该事务在事务完成时无法释放数据,或者万一该事务在其上运行的系统崩溃,则数据将被解锁,使得其它事务不必无限制地等待来访问该数据。常规上,等待所选数据的每一事务将必须等待直到先前对该数据排队的所有事务完成其对该数据的使用,或直到分配给每一事务的租用期满。
随着等待访问租用数据的事务数量的增加,可能会有显著的延迟。另外,控制数据租用的系统在尝试访问数据时可造成瓶颈。作为对数据访问的单个控制点控制租用的系统在试图响应租用请求时可导致事务延迟。此外,由于系统可能正在接收对同一所选数据的多个请求,因此处理这多个且可能重复的请求将浪费计算周期,从而导致对寻求同一数据或任何其它数据的事务的进一步延迟。
概述
一种增量分页器用原子的、隔离的事务来维护数据库。当一事务试图对该数据库作出改变时,该增量分页器将改变储存在写缓冲区中,并在介入的事务没有在字面上或实质上改变该事务所依赖的数据库的状态时应用改变。该增量分页器通过将写缓冲区与数据库的当前状态联合以形成表示该数据库的状态的新数据结构来应用改变以提交事务。该增量分页器根据该增量分页器所遵守的快照来接合写缓冲区以维持效率,以便保留数据库的所选状态。该增量分页器通过将所选数据移至持久存储来使得数据库的所选部分持久。该增量分页器还提供持久存储和当前事务之间的高速缓存对象以促进对数据的高效访问。
提供本概述以便用简化的形式介绍将在以下详细描述中进一步描述的一些概念。本概述并不旨在确定所要求保护的主题的关键特征或必要特征,也不旨在用于帮助确定所要求保护的主题的范围。
附图简述
该详细描述将参考附图来描述。在附图中,三位数参考标号的最左边一位或四位数参考标号的最左边两位标识了该参考标号首次出现的附图。在不同附图中使用相同的参考标号来指示相似或相同的项目。
图1示出了数据库的初始、当前状态。
图2示出了针对数据库的第一事务。
图3-6示出了使用缓冲区来执行并提交给数据库的事务。
图7-11示出了使用累积写缓冲区来执行的事务。
图12示出了使用写缓冲区执行事务的一种模式。
图13示出了使用单写缓冲区执行的事务。
图14示出了使用单写缓冲区来执行事务的一种模式。
图15示出了在将第一事务作为介入事务执行的同时针对数据库执行的第二事务。
图16-20示出了在唤醒介入事务时对当前事务的提交和中止。
图21示出了在唤醒介入事务时确定何时提交或中止一事务的一种模式。
图22-27示出了使用读和写缓冲区执行并提交给数据库的潜在竞争的事务。
图28示出了使用读和写缓冲区执行事务的一种模式。
图29示出了使用读和写缓冲区在唤醒介入事务时确定何时提交或中止一事务的一种模式。
图30-31示出了缓冲区的接合。
图32-34示出了使用快照对象来保留数据库的所选状态不被接合到后续状态中。
图35示出了在保留一个或多个所选状态的同时接合缓冲区的一种模式。
图36-27示出了变为持久的缓冲区。
图38示出了使对象变得持久的一种模式。
图39示出了高速缓存对象的使用。
图40示出了创建并维护高速缓存对象的一种模式。
图41示出了先前描述的对象集合。
图42示出了适用于执行先前所描述的数据库事务和操作的示例性操作环境。
详细描述
概览
术语“增量分页器”描述了用于在维持数据库的完整性并保留数据库的所选状态的同时处理对数据库的改变的方法和系统的各实施例。通过遵守识别的对象之间的指针的不变性,该增量分页器保留了数据库状态的完整性,同时还维持了效率。
在一种模式中,该增量分页器通过使用当前状态指针来跟踪数据库的当前状态来管理事务,其中该当前状态包括储存在该数据库中的所有数据的完整映射。在该完整映射中,对于为该数据库定义的每一地址或地址表示,将有一个数据值或空值。部分映射可包括该增量分页器用于储存一事务试图应用于在启动该事务时存在的数据库的当前状态的改变的一个或多个对象。如果该事务被提交给数据库,则该部分映射被追加到该数据库的原始当前状态以形成新的当前状态。当通过新应用的部分映射来访问该新的当前状态时,该部分映射中对地址的值分配取代了原始状态中的分配,且因此有效地盖写或改变了数据库的原始状态中的数据值。
为阐明并区分本描述中使用的术语,数据库的映射指的是对数据值的地址值分配。数据库的完整映射指的是数据库中的所有地址值对储存在这些地址处的数据值(或空值)的一组完整的分配。部分映射指的是一事务对数据库作出或试图作出的一组改变或盖写,包括该事务试图写入数据的地址、以及该事务试图写入到该地址的数据值。当一事务被提交给数据库时,一部分映射可被添加到先前的完整映射,得到该数据库的经更新的当前映射。由此,数据库的当前完整映射可包括一系列部分映射,其中后来添加的部分映射可盖写或改变包括在先前的部分映射中的地址分配。
数据库的状态指的是储存在存储器、盘或大容量存储中的对象集合,在该对象集合中储存了数据库的映射。状态中的对象包括增量分页器为事务创建的用于储存该事务试图写入数据库的改变的缓冲区,以及其中可收集缓冲区的其它对象。缓冲区、其它对象以及这些对象如何连接、接合和以其它方式操纵将在以下详细描述。数据库的当前状态包括呈现出数据库的当前的、完整的映射的那些对象。如以下解释的,增量分页器还可维护其它状态,诸如当启动一事务时该数据库的状态。增量分页器跟踪该状态以确定该事务是否应当被提交给数据库。增量分页器还维护所选状态以保留这些状态以及这些状态所表示的数据库的映射以供稍后使用。
当每一事务启动时,增量分页器允许该事务基于在启动该事务时存在的数据库的状态来执行。该事务然后创建诸如写缓冲区等至少一个对象,并将该写缓冲区指向在启动该事务时存在的数据库的状态。增量分页器可使用一系列缓冲区,其中每一缓冲区储存该事务试图应用于数据库的单个改变,其中每一缓冲区指向保留该数据库的状态的前一缓冲区。或者,增量分页器可将一事务试图作出的所有改变储存在一累积写缓冲区中,该累积写缓冲区指向当启动该事务时的数据库的当前状态。指向启动事务时的状态的缓冲区或其它对象表示该事务试图应用于数据库的改变的部分映射。
如果增量分页器没有发现关于一个或多个介入事务阻止其应用当前事务的指示,则增量分页器通过将增量指针用于跟踪数据库的当前状态的当前状态指针改为指向为事务创建的最后一个缓冲区,或唯一缓冲区来提交事务。将当前状态指针改为指向缓冲区创建了该数据库的新的、经更新的状态,这可能改变数据库的完整映射中的数据值。
增量分页器可使用读缓冲区和写缓冲区来处理事务。读缓冲区跟踪该事务所访问的数据。当当前事务完成时,增量分页器使用读缓冲区来确定是否要提交该事务。如果读缓冲区显示当前事务读取了被介入事务盖写或改变的数据,则增量分页器可中止该事务。
在增量分页器提交了对数据库的多个改变之后,增量分页器可为了效率起见接合数据库的当前状态中的缓冲区或其它对象。增量分页器可将一个部分映射中的多个对象与另一部分映射中的对象接合。两个部分映射中较新的一个中的地址分配将被添加到或替换包括在较旧的部分映射中所包括的分配。接合可得到一个或多个接合的对象,包括存储器对象或持久对象,或者增量分页器可通过将储存在缓冲区中的改变应用于数据库的原始状态来接合缓冲区。增量分页器提供快照指针以允许保留所选状态。与快照指针相关联的任何状态将不与表示对由该快照指针保留的状态所做的改变的缓冲区接合。
增量分页器允许将数据库和对数据库所做的改变变为持久的。增量分页器可将用于维护数据库的当前状态的一个或多个对象复制到持久的、非易失性存储中。增量分页器还提供了高速缓存对象以提供对储存在大容量介质中的数据库的当前状态的一部分,包括该增量分页器移至非易失性存储以使这些部分变得持久的当前状态的部分的更快速访问。增量分页器可使用高速缓存对象来储存数据库状态中的空数据范围以便于范围查询。
使用写缓冲区来处理事务
图1示出了数据库的当前状态100。当前状态100包括数据库的示例性原始状态110。数据库可驻留在易失性存储器或非易失性存储中。数据库分页器使用当前状态指针120来指向仅包括图1中的原始状态110的当前状态。
原始状态110是维护当前各自储存了一空值的五个记录,即记录0 130、记录1 140、记录2 150、记录3 160和记录4 170的对象。注意空值无需实际上存储在原始状态中。原始状态110还可包括事务可向其应用改变的任何初始状态,包括空和非空值。
图2示出了包括多个指令210-270的一个示例性事务,即事务1 200。在某些指令,诸如指令1 200“x=Read(3)”试图从数据库中读取数据。其它指令,诸如指令3 240“Write(2,x)”试图向数据库应用将导致将一值分配或重新分配给数据库中的地址的改变。
图3示出了增量分页器针对数据库启动诸如事务1 200等事务的一种模式。事务1 200以事务开始指令trans_start 210开始。在启动事务1 210之后,当前状态指针120继续指向在启动该事务时数据库的状态,即原始状态110。增量分页器创建第一写缓冲区310,其中增量分页器将储存事务1 200试图应用的改变。增量分页器将写缓冲区310指向启动事务2 200时的状态,该状态由当前状态指针120指示。增量分页器还创建事务指针320,并将事务指针320指向第一写缓冲区300,而第一写缓冲区300进而指向当前状态。
图4-6示出了增量分页器如何处理事务1 200。参考图2,指令1 220“x=Read(3)”从地址3中读取x的当前值,即空值。指令2 230“x=x+1”将x的值递增1,这在这一情况下将x的值改为1。指令3 240“Write(2,x)”指示计算系统将x的值写入地址2。
增量分页器不将值1写入原始状态110中的地址2。相反,如图4所示,增量分页器创建第二写缓冲区410。第二写缓冲区410指向第一写缓冲区310,并且增量分页器将事务指针320切换为指向第二写缓冲区410以维护数据库的部分映射,该部分映射指示事务2200将如何修改启动事务时的数据库的状态。增量分页器将把值1写入地址2的改变储存在第二写缓冲区410中。
图5示出了增量分页器对事务1 200试图对数据库作出的第二改变的响应。指令4 250“Write(4,″DOG″)”指示计算系统将串“DOG”储存在地址4中。再一次,增量分页器并非写入对原始状态110的改变,而是创建指向第二写缓冲区410的第三写缓冲区510。增量分页器还将事务指针320改为指向第三写缓冲区510以保留数据库的状态(因为事务1 200将修改该状态),并将串“DOG”储存在第三写缓冲区510中。由此,从事务指针320中读取的对于事务21200的数据库的部分映射包括地址2储存值1以及地址4储存串“DOG”的修改。然而,事务既没有改变原始状态110,也没有改变当前状态指针120所指示的当前状态。
图6示出了增量分页器如何将事务1 200提交给数据库。由于事务指针320通过写缓冲区510、410和310,或指向与当前状态指针120所指向的相同的状态,因此增量分页器确定在事务1 200被提交给数据库之前没有介入事务改变了数据库的当前状态。由此,增量分页器通过将当前状态指针120改为指向为事务1 200创建的部分映射来将事务1 200提交给数据库,其中该部分映射包括写缓冲区310、410和510修改的原始状态110。由此,增量分页器将当前状态指针120改为指向第三写缓冲区510,即事务1 200添加的最后一个写缓冲区。增量分页器然后删除事务指针320。当前状态指针120现在指向数据库的经更新的状态,该经更新的状态包括由储存在写缓冲区310、410和510中的改变更新的原始状态110。
使用图6的当前状态,当一事务访问数据库时,增量分页器使用在启动该事务时存在的数据库的状态,这由当前状态指针120来标识。使用当前状态,如果一事务试图标识缓冲区510中地址4的内容,则它将找到串“DOG”。另一方面,如果该事务寻找内容地址2,则它不会在缓冲区510中找到。由此,事务将前进到缓冲区410,在那里事务将找到值1。在图6的示例中,如果事务寻找另一值,则事务将访问所有缓冲区,直到发现原始状态110仅包括对于其它地址的空值。由此,增量分页器通过向数据库的当前状态添加缓冲区或其它对象来改变数据。
增量分页器的一个恒定性是它遵守其所创建的每一指针的不变性。该不变性恒定性维持了每一对象所依赖的,并且因此所指向的状态永不改变,只要有一指针指向该对象。例如,第一写缓冲区310指向数据库的原始状态110。不论事务1200应用于数据库的后续改变如何,第一写缓冲区310都始终指向击仅包括原始状态110的数据库状态。类似地,第二写缓冲区410指向第一写缓冲区310。第二写缓冲区410还指向数据库的不变状态,包括原始状态110和写缓冲区310,这不会修改原始状态110。第三写缓冲区510指向第二写缓冲区410,由此指向其自己的数据库的局部映射,包括如由第二写缓冲区410修改的原始状态110。这些指针的不变性具有以下描述的优点。
累积写缓冲区和重写单写缓冲区
在刚才描述的模式中,增量分页器创建一新的写缓冲区以启动事务并储存该事务试图应用于数据库的每一改变。或者,增量分页器可采用诸如累积缓冲区等不同类型的对象,或者增量分页器可盖写现有缓冲区以储存一个或多个改变。
图7示出了增量分页器使用累积写缓冲区来处理事务。如图3中的示例一样,增量分页器通过创建指向当启动事务时存在的当前状态(如由当前状态指针120所指示的)的第一累积缓冲区710来启动事务1 200。增量分页器再次创建事务指针320并将其指向最近创建的写缓冲区以维护将被事务1 200修改的数据库的部分映射。
图8示出了增量分页器通过添加指向第一累积缓冲区710的第二累积缓冲区810来继续处理事务。增量分页器将事务指针320指向最近创建的写缓冲区,即第二累积缓冲区810。增量分页器将事务1 200试图应用于数据库的改变储存在第二累积缓冲区810中,并将地址2的值设为1。第二累积缓冲区810不不表现为累积的,因为事务1 200迄今仅尝试了一次改变。
图9示出了增量分页器通过添加指向第二累积缓冲区810的第三累积缓冲区910来继续处理事务1 200。增量分页器将事务指针320指向最近创建的写缓冲区,即第三写缓冲区910。增量分页器现在储存事务1 200试图应用于数据库的改变,并将地址2的值设为1,并且还储存地址4处的串“DOG”。
图10和11示出了增量分页器使用累积写缓冲区的一种模式的优点。图10示出了当事务1200尝试的所有改变都被储存在第三累积缓冲区910中时,事务1 200将应用于数据库的所有改变的部分映射被包括在单个对象,即累积写缓冲区910中。该部分映射即使在如图10的示例中那样省略累积缓冲区710和810时也将被保留。
根据不变性恒定性,没有事务可以干涉或访问一事务的中间状态,因此,不需要保留写缓冲区710和810来维持事务指针320所指示的状态的完整性。结果,在其所储存的改变也被储存在最近创建的累积缓冲区910中之后,不需要维护累积缓冲区710和810。
由此,如图11所示,当增量分页器创建并写入每一新的累积缓冲区时,增量分页器可丢弃之前的缓冲区。第一阶段1100示出在第一改变之后的事务1200的当前状态已被写入第二累积缓冲区810中,其中地址2的值被设为1。由于第二累积缓冲区810包括储存在第一写缓冲区710中的任何改变,因此在第二阶段1110,增量分页器可以将第二累积缓冲区810指向第一累积缓冲区710所指向的状态,并释放第一累积缓冲区710及其指针而不改变由事务指针320所指示的状态。事务指针320所指向的状态更短,因为它不通过仅包括储存在第二累积缓冲区810中的相同数据的一个子集的缓冲区。在第三阶段1120中,增量分页器可以释放用于储存第一累积缓冲区710的存储器,从而节省了存储器用于其它用途。如果增量分页器应用了如图11所示的类似阶段来储存事务1200的下一改变,则结果将与图10所示的相同。
图12示出了增量分页器用于处理事务的一种模式。流程图1200在框1202接收事务开始。框1204创建将指向该事务试图应用于数据库的任何改变的事务指针。框1206创建第一写缓冲区,并将该缓冲区指向接收到该事务时存在的当前状态。框1208将事务指针指向第一写缓冲区,第一写缓冲区进而指向启动该事务时的当前状态。
框1210确定事务是否试图向数据库应用改变而非例如仅仅从数据库读取数据。如果是,则框1212创建一附加写缓冲区并将其指向先前创建的缓冲区。该附加写缓冲区可以是单写缓冲区或累积写缓冲区。如果使用了累积写缓冲区,则在一种模式中,框1212将该附加累积缓冲区指向前一缓冲区所指向的状态,并如参考图11所述地释放前一缓冲区。
框1214将事务试图应用于数据库的改变储存在该附加写缓冲区中。框1216将事务指针指向该附加写缓冲区。框1218确定该事务是否试图向数据库应用任何另外的改变。如果是,则流程图1200循环到框1212,并且框1212创建一附加缓冲区。另一方面,如果框1218确定该事务没有试图应用另外的改变,则框1220将如在下一节中所述地提交改变。框1224等待另一事务的接收。
另一方面,如果框1210确定该事务没有试图向数据库应用任何改变,则框1222释放第一写缓冲区和事务指针,因为它们不再需要。框1224再次等待另一事务的接收。
增量分页器还可如图13所示使用单个可重写写缓冲区来代替使用一系列累积缓冲区。在第一阶段1300,增量分页器接收事务并创建单写缓冲区1310,并将其指向当前状态。增量分页器然后创建切换事务指针1320并将其指向单写缓冲区1310。切换指针1320如下所述保持了增量分页器中的指针的不变性。以此方式盖写或重写缓冲区通过使用单个累积缓冲区来储存事务试图应用的改变而非使用多个缓冲区来储存每一改变保留了增量分页器所识别的不变性恒定性。
在使用单写缓冲区1310的第二阶段1330,增量分页器将切换指针1320指离单写缓冲区1310,并用事务所指示的改变或另外的改变来更新单写缓冲区。如上所述,增量分页器保留所有指针的不变性。由此,在技术上,如果切换指针在它向缓冲区1310写入改变时继续指向单写缓冲区1310,则将违反该不变性恒定性:切换指针指向的状态将看到变化。由此,在一种模式中,增量分页器使用它能指离单写缓冲区1310的切换指针1320。
在第三阶段1340,一旦增量分页器更新了单写缓冲区,则增量分页器将切换指针1320指回单写缓冲区1310以维持事务试图应用于数据库的改变的部分映射。在第四阶段1350,增量分页器再次将切换指针1320指离单写缓冲区1310,并更新单写缓冲区以添加事务指示的另一改变。在第五阶段1360,一旦增量分页器向单写缓冲区添加了另外的改变,该增量分页器再一次将切换指针1320指回单写缓冲区1310以维持部分映射。
注意,该增量分页器不需要字面上使用实际被指离缓冲区1310的切换指针1320。为示出逻辑上保持了不变性恒定性,该增量分页器被描述为使用由切换指针1320指示的可重写缓冲区。或者,如果重写原子地发生使得在重写发生时系统中没有一部分解除对指针的引用,则可以改为使用普通的事务指针320,以便仍有效地保持恒定性:如果没有人观察到其值,则一指针不是指针。因此,在这一受限情况下,增量分页器使用原地重写,因为它保持了不变性恒定性。
图14示出了图13中所描绘的增量分页器用于通过使用单写缓冲区来处理事务的模式。流程图1400在框1402接收事务时开始。框1404创建将指示事务试图应用于数据库的改变的部分映射的切换指针。框1406创建单写缓冲区并将该缓冲区指向接收事务时的当前状态。框1408将切换指针指向单写缓冲区以指示该事务试图应用于数据库的部分映射。
框1410确定该事务是否试图向数据库应用改变。如果是,则框1412将切换指针指离单写缓冲区。框1414将改变储存到单写缓冲区中。如图13所示,该单写缓冲区是累积的,因此,可向该单写缓冲区添加多个改变。框1416将切换指针指回单写缓冲区。
框1418确定该事务是否试图向数据库应用任何另外的改变。如果是,则流程图1400循环到框1412,并且框1412创建一附加缓冲区。另一方面,如果框1418确定该事务没有试图应用另外的改变,则框1420将试图如在下一节中所描述的那样提交改变。框1214等待另一事务的接收。
另一方面,如果框1410确定该事务没有试图向数据库应用任何改变,则框1422释放单写缓冲区和切换指针,因为它们不再需要。框1424等待另一事务的接收。
提交事务
增量分页器支持用于确定何时提交事务的不同模式。增量分页器允许多个事务并发地访问启动每一事务时存在的数据库状态。然而,当多个事务并发地运行时,第一个被提交给数据库的事务可改变其它并发执行的事务所依赖的数据库状态。基于过时的或被取代的数据库状态的事务将导致在被提交给数据库时的无效结果。由此,增量分页器仅在介入事务没有干涉当前事务所依赖的数据库状态时才提交当前事务。
图15示出了增量分页器与事务1 200同时地处理的第二事务,即事务2(Tx2)1500,这导致可能冲突的事务。面对可能冲突的事务,增量分页器确定要将哪一事务提交给数据库并中止哪一事务。事务2 1500调用多个指令1510-1570。诸如指令1 1520“x=Read(0)”等某些指令试图从数据库中读取数据,而诸如指令4 1550“Write(3,″CAT″)”等某些指令试图向数据库应用改变。
图16示出了其中增量分页器接收并并发地处理两个事务1 200和事务21500的情形。这两个事务中的任一个都可在另一个之前、在任一事务被提交给数据库之前启动。这两个事务在当前状态指针120继续指向原始状态110(此时是当前状态)时启动。
增量分页器如上所述地通过创建指向由当前状态指针120指向的原始状态110的第一写缓冲区310来启动事务1 200,并创建指向对该事务最近创建的写缓冲区的事务指针320。增量分页器创建储存事务1 200试图对数据库作出的改变的附加写缓冲区410和510。
对于事务2 1500,增量分页器创建指向原始状态110的第一写缓冲区1610以及指示对该事务最近创建的写缓冲区的事务指针1620。类似地,增量分页器为事务2 1500创建附加写缓冲区。在图16中,指令1 1520“x=Read(0)”和指令2 1530“y=Read(1)”都从原始状态110读取空值。由此,条件指令3 1540“If y=x then”为真,并且指令4 1550“Write(3,″CAT″)”执行。增量分页器创建指向第一写缓冲区1610的附加写缓冲区1630,将指令4 1550指示的改变储存在附加写缓冲区1630中,并将事务指针1620指向附加写缓冲区1630。事务指针320和事务指针1620都指向包括每一事务将应用于数据库的改变的部分映射。
事务1 200和事务2 1500可能对数据库作出冲突的改变,或者诸如指令31540等条件指令可能依赖于另一事务可能会改变的数据。以下描述增量分页器以不同方式解决这些潜在冲突的模式。
当介入事务改变当前状态时中止事务
图17和18示出了增量分页器用于处理潜在的冲突事务的一种模式:通过在增量分页器提交了改变数据库状态的介入事务之后中止一事务。在图17中,增量分页器已如上对于图6所描述的那样将事务1200提交给数据库:事务指针320被移除,并且当前状态指针120被切换为指向为事务创建的最后一个写缓冲区510。在将事务1 200提交给数据库之后,增量分页器确定事务2 1500已完成执行并试图将其提交给数据库。
在确定是否将事务2 1500提交给数据库时,增量分页器确定诸如事务1200等介入事务是否改变了在当前事务,即事务2 1500启动时存在的数据库状态。为作出这一判定,增量分页器通过确定第一写缓冲区1610指向什么状态来比较事务2 1500启动时的数据库状态。增量分页器然后将其与当前状态指针120所指向的数据库的当前状态进行比较。换言之,增量分页器将当前状态指针120与事务指针1620和插入的写缓冲区1610和1630进行比较以确定它们是否都指向同一对象。在将事务1 200提交给数据库之后,增量分页器确定当前状态指针120指向写缓冲区510,而事务2 1500通过其第一写缓冲区1610指向原始状态110。
由于事务2 1500指向除当前状态指针120指示的当前状态之外的其它状态,因此增量分页器中止事务2 1500。图18示出了增量分页器通过删除写缓冲区1610和1630以及事务指针1620来释放不再成为数据库的当前状态的一部分的存储器而中止事务2 1500。
中止对于当前状态的任何改变的事务是避免提交冲突事务的一种抗风险方法。如在图16-18的示例中那样,事务1 200不改变当执行事务2 1500时存在的数据库状态中的任何值。然而,有可能介入事务1 200已经改变了事务21500所依赖的数据。事务1 200改变了数据库的当前状态,且因此可能已改变了事务2 1500所依赖的数据。
尽管事务2 1500被中止,但该事务可以如图19和20所示地重新启动。在图19中,增量分页器在提交事务1 200之后启动事务2 1500。由此,当事务2 1500被启动时,增量分页器创建了指向在重新启动事务2 1500时存在的状态的第一写缓冲区1910。该状态由当前状态指针120来指示,该指针指向由事务1 200添加到状态的写缓冲区510。增量分页器然后创建最初指向写缓冲区1910的事务指针1920。增量分页器添加增量分页器向其储存事务2 1500试图应用于数据库的改变的附加写缓冲区1930,然后增量分页器将事务指针1920改为指向附加写缓冲区1930以指示表示事务2 1500试图应用于数据库的改变的部分映射。
此时,当增量分页器确定事务2 1500完成并且试图将事务提交给数据库时,增量分页器发现没有介入事务将数据库的当前状态从事务2 1500所依赖的状态改变。事务指针1920通过写缓冲区1930和1910指向写缓冲区510。当前状态指针仍指向写缓冲区510,因此,事务指针1920仍指向当前状态。
图20示出了增量分页器将事务2 1500提交给数据库。增量分页器将当前状态指针120改为指向事务2 1500添加的最后一个缓冲区,即写缓冲区1930。增量分页器然后删除事务指针1920。当前状态指针现在所指向的当前状态包括被储存在写缓冲区410和510中的事务1200所应用的改变以及储存在写缓冲区1930中的事务2 1500所应用的改变所修改的原始状态110。
图21示出了增量分页器用于确定是提交还是中止事务的该第一模式。流程图2100在框2102处开始。框2102确定一完成的事务何时试图提交给数据库,并且流程图2100循环到框2102直到一事务试图提交给数据库。当框2102检测到一完成的事务试图提交时,框2104确定当前状态是否与如由用于当前事务的事务指针所指示的当启动事务时存在的状态相同。换言之,框2104确定为事务创建的第一写缓冲区是否指向当前状态指针所指向的同一状态。如果是,则框2106将当前状态指针指向为该事务创建的最后一个缓冲区,这是事务指针也指向的缓冲区,从而完成作为提交事务的结果的对数据库的更新。框2108删除事务指针,从而释放相关联的存储器。流程图2100循环到框2102以检测下一完成的事务试图提交给数据库。
另一方面,如果框2104确定当前状态不与当启动事务时存在的状态相同,则框2104确定当前状态已改变。框2110释放事务的写缓冲区。框2112删除事务指针,完成事务的中止。如上所述,中止的事务可以被重新启动,并且在事务完成并试图提交时,增量分页器将确定该事务是否应被提交给数据库。
防止事务被不必要地中止的读缓冲区
代替增量分页器只要当前事务指向不匹配当前状态的状态就中止当前事务,增量分页器可以改为在介入事务写入了当前事务已读取的数据时中止当前事务。只要当前状态已改变就中止当前事务确保不会将冲突的改变应用于数据库。然而,当可能存在同时执行的许多事务,并且这些事务中的某一些可能涉及冗长或复杂的计算时,中止事务浪费了计算资源。由此,如果介入事务没有访问或改变当前事务读取或依赖的任何数据,增量分页器就不必中止该当前事务。
一种模式的增量分页器为每一事务创建一读缓冲区。读缓冲区跟踪事务访问的任何数据。当完成的事务视图提交给数据库,但发现一介入事务已经改变了该数据库的状态时,增量分页器可以将读缓冲区与该数据库的当前状态进行比较以确定是否有必要中止当前事务。在另一种模式中,增量分页器在当前状态已改变并且介入事务已改变或盖写了当前事务读取的数据时中止当前事务。在此模式中,增量分页器可以在介入事务向当前事务读取的地址写入数据时中止事务,或者增量分页器可以将当前事务读取的实际数据与介入事务写入的数据进行比较以确定该数据值是否实际改变。
图22-24示出了使用读缓冲区并且在介入事务写入了当前事务读取的数据时中止事务的一种模式的增量分页器。图22示出了针对数据库的当前状态执行的两个事务,即事务1 2200和事务2 2250。当前状态指针120指向原始状态110,由此指示当前状态或数据库的当前状态。对于事务1 2200,增量分页器创建读缓冲区2210、写缓冲区2220和事务指针2230。如上所述,增量分页器可以对每一事务创建一个或多个写缓冲区。如果读缓冲区的大小有限制或者出于其它原因,增量分页器还可创建多于一个读缓冲区。增量分页器将读缓冲区2210指向当前状态,将写缓冲区2220指向读缓冲区2210,并将事务指针2230指向写缓冲区2220。相应地,对于事务2 2250,增量分页器创建读缓冲区2260、写缓冲区2270和事务指针2280。增量分页器将读缓冲区2260指向当前状态,将写缓冲区2270指向读缓冲区2260,并将事务指针2280指向写缓冲区2270。
用于事务1 2200的读缓冲区2210指示事务1 2200已经读取了地址3处的数据。用于事务2 2250的读缓冲区2260指示事务2 2250也已经读取了地址3处的数据。然而,即使每一事务读取了相同的数据,也没有一个事务试图改变该地址处的数据。由此,增量分页器并没有被迫中止任一事务。
与空的写缓冲区一样,读缓冲区不改变数据库的状态。因此,增量分页器的各实施例可采用不出于数据库的当前状态的读缓冲区,就如同它曾经是其中储存了数据的对象一样。相反,增量分页器可以被储存在该增量分页器可创建以储存事务试图应用的改变的部分映射之外。读缓冲区可以被储存在一单独的位置中,并且事务指针可以维护指示该读缓冲区的位置的一单独指针。
如果增量分页器仅在介入事务改变了当前事务读取的地址处的数据时才中止当前事务,则读缓冲区应当储存所读取的地址和值,如以下参考图25-27所描述的。另一方面,如果增量分页器将在介入事务盖写了当前事务曾读取的数据时中止该事务,则即使介入事务写了相同的值,读缓冲区也只需包括该事务所读取的一个或多个地址,如在图22-24中所示。
图23示出了在增量分页器向数据库提交了事务1 2200之后数据库的状态。增量分页器将当前状态指针120改为指向为事务1 2200创建的最后一个写缓冲区2220,并删除事务指针2230。一旦事务2 2250完成,增量分页器就确定它是否应提交事务2 2250。再一次,由于数据库的当前状态在增量分页器提交事务2 2250之前改变,因此在如先前参考图15-21所描述的确定是否提交事务的模式中,增量分页器将中止事务2 2250。相反,当前模式作出更实质性的评估。
在此模式中,即使数据库的当前状态已改变,增量分页器也不中止当前事务,除非介入事务将数据写入了当前事务所访问的地址。增量分页器比较事务22250的读缓冲区2260以确定介入事务,即事务1 2200是否写入了事务2 2250从中读取数据的地址,由此改变了处理或事务2 2250所依赖的状态。事务22250根据读缓冲区2260仅从地址3读取数据。然而,检查了当前状态指针120指示的当前状态,事务1 2200根据写缓冲区2220仅将数据写入地址4。由此,增量分页器将事务2 2250提交给数据库。
图24示出了增量分页器将事务2 2250提交给数据库的当前状态。增量分页器将事务2 2250的读缓冲区2260指向当前状态指针所指示的对象,即事务1 2200的写缓冲区2220。增量分页器然后将当前状态指针120改为指向事务22250的写缓冲区2270,从而将事务2 2250提交给数据库。
图25-27示出了其中增量分页器仅在介入事务不仅写入了介入事务写入数据的地址,而且介入事务还实际改变了当前事务读取的数据值时才中止当前事务的较不抗风险的模式。图25示出了针对数据库的当前状态执行的两个事务,即事务1 2500和事务2 2550。当前状态由当前状态指针120指示,该指针指向数据库的原始状态110。对于事务1 2500,增量分页器创建读缓冲区2510、写缓冲区2420和事务指针2530。增量分页器将读缓冲区2510指向那时的当前状态,将写缓冲区2520指向读缓冲区2510,并将事务指针2230指向写缓冲区2520。相应地,对于事务2 2550,增量分页器创建读缓冲区2560、写缓冲区2570和事务指针2580。增量分页器将读缓冲区2560指向那时的当前状态,将写缓冲区2570指向读缓冲区2560,并将事务指针2580指向写缓冲区2570。
与图22-24的示例形成对比,用于事务1 2500的读缓冲区2510指示事务1 2500读取了地址3的值,并且从地址3读取的值为空。用于事务2 2550的读缓冲区2560指示事务2 2500也读取了地址3的值,并且也发现从地址3读取的值为空。用于事务2 2550的写缓冲区2570储存对地址3的值的改变,从而将储存的值改为串“CAT”。
图26示出了在增量分页器向数据库提交了事务2 2550之后数据库的当前状态。因此,增量分页器将当前状态指针120改为指向储存事务2 2550应用于数据库的任何改变的写缓冲区2570,并丢弃事务指针2580。在此模式中,事务1 250一旦完成,增量分页器确定事务1 2500是否读取事务2 2550改变的数据。
增量分页器将事务1 2510的读缓冲区2510与当前状态指针120指示的数据库的当前状态进行比较。根据读缓冲区2510,事务1读取了地址3并发现值为空。增量分页器还跟随当前状态指针120指示的数据库的当前状态,并发现事务2 2550将地址3处储存的值改为“CAT”。由此,事务1 2500试图应用于数据库的任何改变可以基于现在过时的数据。
因此,增量分页器如图27所示地中止事务1 2500。增量分页器释放或删除读缓冲区2510、写缓冲区2520和事务指针2530,并且增量分页器保持当前状态指针120指向储存事务2 2550应用于数据库的改变的写缓冲区2570。如有需要,事务1 2200随后可被如上所述地重新启动。
注意,即使事务2 2550向事务1 2500读取的地址写入了新值,事务2 2250写入的数据也可能没有改变事务1 2500的结果。然而,为确定因事务2 2550写入的数据而导致的事务1 2500将改变的结果,事务1 2500必须被重新执行。这一模式的增量分页器不中止事务1 2500仅仅是因为当前状态已改变,但是提供了对它是否应当中止缺少时间来重新运行事务1 2550的当前事务的某一实质性分析。
图28示出了增量分页器用于通过创建读缓冲区和单写缓冲区来处理事务以便于确定增量分页器是否应提交事务的更实质性模式的一种模式。增量分页器不限于结合使用读缓冲区来使用单写缓冲区,并且单写缓冲区的选择仅是一种可能的替换。
流程图2800在框2802接收事务时开始。框2804创建将指示该事务试图应用于数据库的改变的部分映射的切换指针。框2806创建一读缓冲区并将其指向启动事务时存在的状态。框2808创建单写缓冲区并将该单写缓冲区指向读缓冲区。框2810将切换指针指向单写缓冲区以指示该事务试图应用的改变的部分状态。
框2812将事务读取的任何数据储存在读缓冲区中。如上所述,在其中增量分页器可在介入事务读取了与当前事务相同的数据的时候中止事务的模式中,读缓冲区只需储存所读取的数据的地址。另一方面,如果增量分页器基于介入事务是否写入了由当前事务读取的数据来确定是否提交该事务,则读缓冲区应储存地址和从该地址读取的数据两者。
框2814确定事务是否试图向数据库应用改变。如果是,则框2816将切换指针指离单写缓冲区。框2818将改变储存到单写缓冲区中。框2820将切换指针指回单写缓冲区。
框2822确定事务是完成还是继续执行。如果事务未完成,则流程图2800循环到框2812以将事务读取的任何数据储存在读缓冲区中。另一方面,如果框2822确定事务完成,则框2824将试图提交事务作出的改变。框2826等待另一事务的接收。
图29示出了其中增量分页器使用读缓冲区来确定是提交还是中止事务的一种模式。流程图2900在框2902处开始。框2902确定完成的事务何时试图向数据库提交,并且流程图2900循环到框2902,直到一事务试图提交到数据库。当框2902检测到试图提交的已完成事务时,框2904确定当前状态自从该事务被启动以来是否已改变。
如果当前状态未改变,则框2912将当前状态指针指向为该事务创建的单写缓冲区,或多个写缓冲区中的最后一个,这是事务指针也指向的缓冲区。框2914删除事务指针,从而完成数据库的更新。如果数据库的当前状态未改变,则增量分页器可以在不检查读缓冲区或搜索对数据库的应用的情况下提交事务。如果当前状态未改变,则没有介入事务将改变当前事务所依赖的数据。流程图2900循环到框2902以检测试图提交到数据库的下一已完成事务。
另一方面,如果框2904确定当前自从事务被启动以来已改变,则框2906确定读缓冲区中列出的数据是否在当前状态中改变。再一次,这一模式的增量分页器在当前状态因增量分页器提交介入事务而已改变时仅检查读缓冲区。如果读缓冲区中列出的数据在当前状态中尚未改变,则增量分页器将提交该事务并且流程图2900前进到框2912。
另一方面,如果框2906在当前状态中发现数据已被写入读缓冲区中的地址,或者如果该地址处的数据的值不同于储存在读缓冲区中的值,则增量分页器中止该事务。框2908释放用于该事务的读和写缓冲区。框2910然后释放或删除用于当前事务的事务指针,从而完成事务的中止。流程图2900然后循环到框2902以等待试图提交的下一事务。
接合事务并保留状态
增量分页器的写缓冲区提供了许多好处。举一个例子,当事务不能被提交并且必须被中止时,增量分页器忽略或删除它为该事务创建的写缓冲区,并且增量分页器不需要重写或撤消否则可能被应用于数据库的错误的或冲突的改变。然而,在增量分页器向当前状态添加许多写缓冲区时,对当前状态中的所有数据的访问可能变得低效。即使在图20的相对简单的示例中,事务也有可能必须通过写缓冲区1930、1910、510、410、310以及原始状态110读回,以确定事务试图读取的数据的值。一种模式的增量分页器接合写缓冲区以确保对数据库的当前状态的高效访问。
图30示出了增量分页器如何接合图20的写缓冲区的一种模式。在图30中,增量分页器通过向数据库的原始状态110应用储存在写缓冲区中的改变来接合写缓冲区。在第一阶段3000,增量分页器识别指示写缓冲区将被串接到的指针的串接指针3010。串接指针3010的好处将在以下进一步描述。增量分页器然后应用储存在指向原始状态110的第一写缓冲区中的改变。如图30所示,第一写缓冲区是空的写缓冲区310。增量分页器通过从当前状态中省略空的写缓冲区来接合诸如写缓冲区310等空缓冲区。
注意,空的写缓冲区310不改变标识事务试图应用于数据库的改变的部分映射。由此,一旦增量分页器创建了储存事务试图应用的改变的写缓冲区,就可立即丢弃空的写缓冲区,或者增量分页器可能甚至不创建空的写缓冲区310。例如,一旦写缓冲区510被添加以改变地址4处的值,则增量分页器的一个实施例可能将写缓冲区510指向启动事务时存在的状态,并丢弃空的写缓冲区310。
在第二阶段3020,增量分页器将储存在下一写缓冲区410中的改变应用于原始状态110,从而用经更新的状态3030来替换原始状态。储存在写缓冲区410中的、将地址2处的值设为1的改变被应用于地址2 3040以创建经更新的后备存储3030。
最终结果3050示出数据库的新状态3060。在新状态3060中,应用储存在写缓冲区510中的改变以将储存在地址4 3070处的值改为串“DOG”,并且应用储存在写缓冲区1930中的改变以将储存在地址3 3080处的值改为串“CAT”。增量分页器现在切换了当前状态指针120以指向新状态3060。增量分页器然后省略接合指针3010。
关于增量分页器的缓冲区接合有四点要注意。首先,即使在接合过程期间,每一指针也继续不变地指向数据库的同一状态。例如,在第二阶段3020,当增量分页器将写缓冲区410中的改变应用于原始状态110以创建经更新的状态3030时,由其它指针指示的状态保持相同。当前状态指针120、写缓冲区510、1910和1930以及接合指针3010都仍指向呈现所有相同值的数据库状态。
第二,如果启动了一个或多个新事务并将其提交以改变数据库的当前状态,则新事务将继续指向数据库的不变状态。在启动新事务时,增量分页器创建指向由当前状态指针120指示的当前状态。如果增量分页器提交该事务,则增量分页器切换当前状态指针120以指向为每一后续事务创建的最后一个写缓冲区。由此,即使在接合写缓冲区时,数据分页器也保留了新事务的状态的不变性。
第三,接合指针3010指示接合过程将停止的点。当增量分页器将附加写缓冲区提交给当前状态时,增量分页器将不接合附加缓冲区,直到增量分页器参与了进一步的接合。接合可以无限制地继续,但是将计算资源专用于不断地接合可能仅仅是几个新的写缓冲区并不是对计算资源的一种高效使用。
第四,如图31所示,增量分页器可以接合缓冲区而不盖写数据库的原始状态110。例如,原始状态110可以被储存在盘存储中,而其访问可能是低效的,或者可能希望维持原始状态110而没有后续事务应用的改变。因此,增量分页器可将写缓冲区接合到一个或多个中间对象。
在图31中,在将写缓冲区接合到中间对象的第一阶段3100,增量分页器在要接合的第一个写缓冲区,即写缓冲区310和原始状态110之间创建一中间接合对象3110。插入接合对象3110不改变数据库内的任何当前状态的不变性:当前状态指针120和写缓冲区310、410、510、1910和1930仍指向数据库的同一状态。接合对象3110以及原始状态110可以在任何期望的存储中维护,包括高速缓冲存储器、存储器、盘或其它形式的存储。
最终结果3120示出增量分页器已将储存在写缓冲区410、510和1930中的所有改变接合到接合对象3110。由此,储存在写缓冲区410中的将地址2处的值改为1的改变并非被应用于原始状态110,而是被储存在地址2 3130处的接合对象3110中。类似地,增量分页器将来自写缓冲区510和1930的改变分别储存在地址3 3140和地址4 3150处的接合对象3110中。增量分页器将当前状态指针120改为指向接合对象3110,接合对象3110进而指向原始状态110。由此,数据库的状态从不改变,并且当前状态指针120继续指向在增量分页器将写缓冲区接合到接合对象3110之前存在的同一数据库状态。
有利的是,试图读取数据的新事务现在只需检查两个数据存储:接合对象3110和原始状态110。如果后者是需要的,则增量分页器可以将接合对象3110的内容接合到原始状态以创建经更新的后备存储。或者,增量分页器可以维持接合对象,并执行写缓冲区到同一接合对象3110的后续接合。再或者,增量分页器可以如以下对于快照进一步描述地创建附加的接合对象。
如上所述,增量分页器维持指针的不变性。在数据库内的接合对象中,表示在添加每一对象时存在的中间状态的缓冲区之间的指针被消除,只要保留了当前状态。然而,如果除来自后续缓冲区的指针之外的其它指针指向一缓冲区,则增量分页器识别的不变性确保该指针指示的状态必须经受得住缓冲区接合。利用增量分页器的指针不变性,增量分页器将遵守指向所选状态的快照指针,并且即使在增量分页器接合快照指针之前或之后的缓冲区时也保留该状态。
图32示出了增量分页器将随快照指针3210一起保留的数据库的当前状态。当前状态指针120指向当前状态,其中原始状态110被写缓冲区3220、3230和3240修改。第一写缓冲区3220将串“PEAR”写入地址0。第二写缓冲区3230将值1写入地址2。第三缓冲区3240将串“DOG”写入地址4。
当增量分页器被指示保留当前状态时,增量分页器创建指向当前状态的快照指针3210。增量分页器插入快照指针3210以保留例如当自动保留常规备份的程序或用户请求请求诸如当前状态等状态的快照时的状态。由于快照指针3210指向所选状态,因此由于增量分页器所遵守的指针不变性,增量分页器将维持该指针和相应的状态。
图33示出了在附加事务改变了当前状态之后数据库的较新状态。第四写缓冲区3310将串“PEACH”写入地址0。第五写缓冲区3320将串“CAT”写入地址4。增量分页器将当前状态指针120切换为指向第五写缓冲区3320。在图33中,第五写缓冲区3320用串“CAT”盖写写缓冲区3240储存在地址4处的串“DOG”。然而,快照指针3310仍指向表示图32的状态的写缓冲区3240。
图34示出了增量分页器所允许的接合。假设其中增量分页器不盖写原始状态110的情况,则增量分页器通过收集在快照指针3210和第一接合对象3410中的原始对象的后备存储之间写缓冲区3220、3230和3240应用的改变来接合数据库的当前状态中的对象。增量分页器然后收集第二接合对象3320中写缓冲区3310和3320应用的改变。当前状态指针120指向第二接合对象3420。第二接合对象3420指向第一接合对象3410,后者进而指向原始状态110。
增量分页器使用单独的接合对象3410和3420来保留快照对象3210的指针的不变性。只要快照对象3210存在,增量分页器就将维持图32的所选状态。由此,例如,在图33和34的当前状态中,增量分页器用写缓冲区3320储存在地址4处的串“CAT”来替换写缓冲区3240储存在地址4处的串“DOG”。然而,在快照指针3210保留的所选状态中,串“DOG”保持被储存在第一接合对象3410中的地址4处。
关于快照指针3210有五点要注意。首先,增量分页器可通过添加快照指针来保留任何所选时刻的数据库状态。其次,增量分页器可包括多个快照指针来保留多个状态。第三,如上对于接合所描述的,增量分页器可以继续接收事务并向数据库提交改变,而同时由于指针的不变性,仍保留一个或多个较早的状态。第四,当快照指针3210保留的状态不再需要时,移除快照指针3210,并且后续接合将释放保留的状态。
第五,快照指针允许增量分页器在单个数据存储中维护多个不同的状态。当保存常规数据库的备份映像以维护当前状态时,每一映像被分开储存,因为后续映像会盖写先前的映像。多个状态可消耗大量的存储,并且备份映像通常被移交给较慢的存储设备以便节省较快的设备中的存储空间。然而,由于增量分页器在较早的状态上构建后续状态,因此快照指针在单个数据存储内保留较早的状态。
图35示出了增量分页器接合缓冲区或诸如先前创建的、现在将被进一步接合的接合对象等其它对象的一种模式。流程图3500以框3502开始。框3502启动对数据库当前状态中的对象的接合。一程序可不时地启动接合,或者用户可启动接合。框3504标识接合起始点,这可包括如图34的示例中的原始状态、最后接合对象、或增量分页器将从中接合添加到数据库的缓冲区的另一点。框3506前进到下一未接合对象。在图33的示例中,从原始状态110开始,框3504标识用于接合作为下一未接合对象,即写缓冲区3220的起始点。
框3508确定是否有除了来自下一个创建的缓冲区之外的指向缓冲区的任何指针。当状态或数据库未改变时,增量分页器可以在接合一系列缓冲区或其它对象时消除指针,但是增量分页器不消除其它指针,诸如来自快照指针3210的指针。如果框3508确定没有除了来自下一缓冲区之外的其它指针,则框3510在接合对象中将该缓冲区与下一个创建的缓冲区相组合。框3512确定是否有可能要接合的另外的对象。另外的对象可包括下一个创建的缓冲区,或者如果数据库中的对象是先前接合的,则可能有要进一步接合的接合对象。如果有可能要接合的另外的对象,则流程图3500循环到框3506以便前进到下一未接合对象。然而,框3512可以确定没有其它对象要接合。例如,如果增量分页器已经完整地接合了数据库,则增量分页器将到达未接合的当前状态指针120。当框3512确定没有要接合的另外的对象时,框3514完成接合。完成接合可能例如发送或记录确认操作完成的消息。
另一方面,框3508可确定有来自除状态中的下一对象之外的指针。例如,如图32-34所示,快照指针3210可以指向一对象以保留该对象所表示的状态。当框3508确定有另一指针时,流程图3500前进到框3512以确定是否有可能要接合的另外的对象。
使状态变得持久
增量分页器允许使数据库的所选部分变得持久。增量分页器将数据库的所选部分提交给非易失性存储以保留它们。
图36示出了数据库的当前状态,包括部分地储存在盘3610,即持久介质,且部分地储存在存储器3620,即易失性介质中的对象。当前状态指针120指向当前状态,该状态包括储存在盘3610上且增量分页器已向其提交了写缓冲区3630和3640中的改变的原始状态110。
在一种模式中,增量分页器允许程序或用户通过插入持久指针3650来使数据库的所选部分变得持久。持久指针3650指向包括要变得持久的对象的数据库状态。在图36中,持久指针3650指向包括第一写缓冲区3630的状态。
如图37所示,增量分页器将包括在持久指针3250所指示的状态中的任何对象移至诸如盘存储3710等持久可存储介质。在本示例中,第一写缓冲区3630被移至盘存储3710。增量分页器允许数据库状态驻留在任何数量的存储介质上。由此,增量分页器向其写入第一写缓冲区3730的盘存储3710可以是与原始状态110所在的盘存储3610相同的存储设备,或者它可以是单独的存储设备。不包括在持久指针3650所指向的状态中的第二写缓冲区3640留在存储器3620中。
一旦增量分页器将持久指针3650所指示的数据库的当前状态的一部分储存到持久存储,则增量分页器可以释放持久指针。增量分页器可以生成确认数据库的所选部分已变得持久的消息。
图38示出了增量分页器使缓冲区变得持久的一种模式。流程图3500以框3802开始。框3802接收持久性请求。框3804定位持久性指针以确定要变得持久的数据库的部分。框3806标识持久性指针和要变得持久的数据库中的最后一个持久存储部分之间的所有对象。框3808将持久性指针和最后一个持久存储之间的所有对象复制到持久存储对象。框3810将指向要变得持久的当前状态的部分的任何指针改为指向持久存储对象。在图37的示例中,增量分页器将写缓冲区3640的指针改为指向持久对象。或者,例如,如果有指向持久指针3650所指向的状态的其它指针,诸如当前状态指针120或快照指针3210,则这些指针也指向由框3808创建的持久对象。
一旦持久性指针3650所指向的状态中的对象被复制到持久对象并且改变了指向该状态的指针,框3812就释放持久性指针所指向的存储器中的对象以释放存储器用于其它用途。框3814删除该持久性指针。框316通过例如向作出持久性请求的用户发送消息或向系统日志添加消息来确认持久性请求的完成。
高速缓存数据
增量分页器还提供了对数据的高速缓存以改善性能。增量分页器允许诸如用参考图7-9描述的一系列累积缓冲区来对数据进行二重存储。一状态内的数据的二重存储不会改变该状态。由此,增量分页器可以将储存在诸如盘存储或其它大容量存储等低速存储中的数据高速缓存在诸如存储器等高速存储中,而不更改状态。
图39示出了包括高速缓存对象3910的数据库的当前状态。高速缓存对象指针3910指向要高速缓存的对象,诸如储存在盘存储3950中的持久对象3930。增量分页器将未储存在持久对象3930(此情况中为读缓冲区3962)中的第一对象指向高速缓存对象3910。
在当前状态中,如果一事务查找地址0的值,则该事务将在写缓冲区3968中找到地址0的当前值,该写缓冲区将串“CAT”写入当前状态。该事务不需要查看比写缓冲区3968远的地方,并且该事务将以存储器检索速度接收到地址0的值。另一方面,如果一事务寻找储存在地址2处的值,则增量分页器将贯穿当前状态来寻找该值直到找到它。如果没有高速缓存对象3910,则增量分页器将去往盘存储3950中的持久对象3930。访问来自盘存储3950的对象与访问存储器3960相比较慢。在存储器3930中创建高速缓存对象3910可提高访问效率。
在图39的示例中,持久对象3930储存一地址范围,诸如储存值1的地址2 3932、储存串“CAT”的地址3 3934、以及储存串“DOG”的地址4 3936处的值。持久对象3930还储存其中没有储存任何数据的一范围的空值3940,直到储存串“ROCK”的地址99 3938。
增量分页器在存储器3960中创建高速缓存对象3910。增量分页器将高速缓存对象3910指向要高速缓存的对象,在此情况中是持久对象3930。增量分页器然后将第一非持久对象,即读缓冲区3962指向高速缓存对象3910。
一旦增量分页器创建了高速缓存对象并改变指针以在当前状态中插入高速缓存对象,增量分页器就填充该高速缓存。在一种模式中,当增量分页器从持久对象3930检索数据时,增量分页器将同一数据储存在高速缓存对象3910中。并且,在花费了时间来访问持久对象之后,增量分页器可以从持久对象3930检索一数据块并将其储存在高速缓存对象3910中。例如,在填充高速缓存对象3910之前,增量分页器为其创建了读缓冲区3962的事务寻找来自地址4的数据,该数据被储存在持久对象3930中地址4 3936处。在访问持久对象3930的同时,增量分页器还可检索包括来自地址2 3932、地址3 3934和其它地址一直到地址99 3938的数据的块的数据,并将该数据储存在高速缓存对象3910中这些地址处。
在增量分页器将从持久对象3930中检索到的数据储存在高速缓存对象3910中之后,对复制到高速缓存对象3910的数据的后续请求将以快得多的存储器速度来执行。由此,如果为其创建了读缓冲区3962的事务接着请求来自地址99的数据,则增量分页器可以从高速缓存对象3910中地址99 3918处检索该数据。类似地,如果为其创建了读缓冲区3964的事务请求来自地址3的数据,则增量分页器可以从高速缓存对象中地址3 3914处检索该数据而无需等待增量分页器从盘存储3950检索数据。
关于增量分页器的高速缓存对象3910有三个特征要注意。首先,高速缓存对象3910的插入不改变增量分页器如何创建和使用数据状态。例如,即使高速缓存对象3910中的地址4 3916储存了串“DOG”,但写缓冲区3966仍可通过将串“BIRD”写入写缓冲区3966中的地址4来改变数据库的状态。在后续的事务中,当前状态指针120所指向的当前状态将发现串“BIRD”被储存在地址4处,而不论高速缓存对象3910在地址4 3916处储存了什么。
其次,如果使用高速缓存对象3910的状态变得持久,则增量分页器不需要重新启动并重新填充高速缓存对象3910。相反,当数据被复制到持久存储时,当被复制到盘的状态中的数据不同于储存在高速缓存对象2910中的数据时,增量分页器可以更新高速缓存对象3910中的数据。或者,增量分页器可以使高速缓存对象3910中当与被复制到持久存储的状态相比时不再为当前的条目无效。这两种技术都修改了旧状态的高速缓存以使其变为经更新的状态的有效高速缓存。通过这样做,增量分页器无限制地重复使用了高速缓存对象。如果高速缓存不能跨更新而保留,则当更新变得持久时,重构高速缓存时将损失效率。
第三增量分页器可以使用高速缓存对象3910来便于范围查询。高速缓存对象可以通过向后备存储发出范围查询来高效地发现空值顺串,并且可在增量分页器维护的高速缓存对象或另一对象的一部分中紧凑地表示这一顺串。例如,空值顺串的表示可以被包括在高速缓存对象的一字段中。在储存在存储器中的对象中维护该表示将提高访问空值串的表示的速度以便于范围查询。例如,如果一事务希望找到在“BIRD”、“CAT”或“DOG”之后的下一宠物串,则当在持久对象3930中在“DOG”之后有一长串空数据3940时,高速缓存对象3910可包括诸如用于地址53920的第一空地址字段中的条目,指示该顺串中的最后一个地址储存空值,或者第一个地址储存非空值以支持范围查询。
图40示出了增量分页器维护高速缓存对象的一种模式。流程图4000以框4002开始。框4002在存储器或其它快速访问存储中创建高速缓存对象。框4004将该高速缓存对象指向被高速缓存的对象。框4006标识指向被高速缓存的对象的对象,并将该对象指向高速缓存对象。框4008将事务读取的地址和数据从被高速缓存的对象储存到高速缓存对象中。如上所述,当增量分页器从被高速缓存的对象中检索数据时,增量分页器较佳地将从与所读取的地址相邻的地址块中检索数据,以便可能转移对后续盘访问操作的需求。
框4010确定指向该高速缓存对象的状态是否要变为持久。如果否,则流程图4000循环到框4008以继续将事务读取的地址和数据储存到高速缓存对象。然而,当框4010确定指向高速缓存的状态要变为持久时,框4012用变为持久的对象中的改变来更新高速缓存条目。或者,增量分页器可以使过时的高速缓存条目无效而非更新它们。一旦框4012更新了高速缓存条目,框4014就将未变得持久的第一个对象指向高速缓存对象。
增量分页器使用的对象
作为概述,图41示出了增量分页器用于方便先前描述的示例性操作的对象。使用新的参考标号来引用本概述中所表示的通用对象。图41示出了一个示例性情形4100,包括储存在持久盘存储4120和存储器4130中的一范围的这些对象。
增量分页器可以使用盘存储4120中的一个或多个持久对象4122和4124。这些对象可以储存如上所述变得持久的原始状态和任何其它状态。例如,持久指针4126被呈现为虚线轮廓,因为它在它所指向的、出现在持久对象4124中的状态变得持久之后被移除。持久对象可被储存在一个或多个设备上。
增量分页器可以包括储存在存储器4130中的多个对象。增量分页器4140可以包括插入在高速缓存的持久对象4122和4124与后续对象之间的高速缓存对象4140。包括快照指针4152保留的状态的快照对象4150指向高速缓存对象4140。快照对象4150包括所选状态,包括接合对象或一系列未接合对象。如上所述,即使包括在保留状态中或稍后被添加到保留状态的对象被接合,快照指针4152也可以保留状态。
由于在接合对象4160处生成了最后一个接合操作,因此诸如读缓冲区4170和写缓冲区4180等多个缓冲区被添加到当前状态。当前状态指针4190指示当前状态。
用于实现示例性实施例的操作环境
图42示出了用于实现增量分页器的示例性操作环境4200。操作环境4200仅为合适的操作环境的一个示例,并非对以上描述的增量分页器的示例性实施例或其它实施例的使用范围或功能提出任何局限。也不应将操作环境4200解释为对示例性操作环境4200中示出的任一组件或其组合具有任何依赖或需求。
实现增量分页器的过程可在诸如程序模块等在操作环境4200中执行的计算机可执行指令的一般上下文中描述。一般而言,程序模块包括执行特定的任务或实现特定的抽象数据类型的例程、程序、对象、组件、数据结构等等。此外,本领域的技术人员可以理解,实现增量分页器的过程可以使用各种计算系统配置来实施,包括手持式设备、多处理器系统、基于微处理器的或可编程消费电子产品、小型机、大型计算机等等。实现增量分页器的过程也可以在其中任务由通过通信网络链接的远程处理设备来执行的分布式计算环境中实践。在分布式计算环境中,程序模块可以位于包括存储器存储设备的本地和远程计算机存储介质中。
参考图42,用于实现增量分页器的过程的示例性操作环境4200包括计算机4210,它包括处理单元4220、系统存储器4230以及将包括系统存储器4230的各类系统组件耦合至处理单元4220的系统总线4221。
计算机4210通常包括各种计算机可读介质。作为示例而非局限,计算机可读介质包括计算机存储介质和通信介质。计算机存储介质的示例包括但不限于,随机存取存储器(RAM);只读存储器(ROM);电可擦除可编程只读存储器(EEPROM);闪存或其它存储器技术;CD ROM、数字多功能盘(DVD)或其它光学或全息盘存储;磁带盒、磁带、磁盘存储或其它磁存储设备;或可以用来储存所期望的信息并可由计算机4210访问的任一其它介质。系统存储器4230包括易失性和/或非易失性存储器形式的计算机存储介质,如ROM 4231和RAM 4232。基本输入/输出系统4233(BIOS)包括(如在启动时)帮助在计算机4210内的元件之间传输信息的基本例程,它通常储存在ROM 4231中。RAM 4232通常包含处理单元4220立即可访问和/或当前正在操作的数据和/或程序模块。作为示例而非局限,图42示出了操作系统4234、应用程序4235、其它程序模块4236和程序数据4237。
计算机4210也可包括其它可移动/不可移动、易失性/非易失性计算机存储介质。仅作示例,图42示出了对不可移动、非易失性磁介质进行读写的硬盘驱动器4241,对可移动、非易失性磁盘4252进行读写的磁盘驱动器4251,以及对可移动、非易失性光盘4256,如CD ROM或其它光介质进行读写的光盘驱动器4255。可以在示例性操作环境中使用的其它可移动/不可移动、易失性/非易失性计算机存储介质包括但不限于,磁带盒、闪存单元、数字多功能盘、数字录像带、固态RAM、固态ROM等等。硬盘驱动器4241通常通过不可移动存储器接口,如接口4240连接到系统总线4221。磁盘驱动器4251和光盘驱动器4255通常通过可移动存储器接口,如接口4250连接到系统总线4221。
上文讨论并在图42示出的驱动器及其关联的计算机存储介质为计算机4210提供了计算机可读指令、数据结构、程序模块和其它数据的存储。例如,示出硬盘驱动器4241储存操作系统4244、应用程序4245、其它程序模块4246和程序数据4247。注意,这些组件可以与操作系统4234、应用程序4235、其它程序模块4236和程序数据4237相同,也可以与它们不同。通常,储存在RAM中的操作系统、应用程序等是从硬盘驱动器4241读取的相应系统、程序或数据的部分,这些部分的大小和范围可取决于所需功能而变化。此处对操作系统4244、应用程序4245、其它程序模块4246和程序数据4247给予不同的标号以说明至少它们是不同的副本。用户可以通过输入设备,如键盘4262;定位设备4261(通常指鼠标、跟踪球或触摸垫);无线输入接收组件4263;或诸如遥控器等无线源向计算机4210输入命令和信息。其它输入设备(未示出)可包括话筒、操纵杆、游戏垫、圆盘式卫星天线、扫描仪等等。这些和其它输入设备通常通过耦合至系统总线4221的用户输入接口4260连接至处理单元4220,但是也可以通过其它接口和总线结构连接,如并行端口、游戏端口、IEEE4294端口或通用串行总线(USB)4298或红外(IR)总线4299。如上所述,输入/输出功能可以经由通信网络以分布式方式来促进。
显示设备4291也通过接口,如视频接口4290连接至系统总线4221。显示设备4291可以是显示计算机4210的输出的任何设备,不限于监视器、LCD屏幕、TFT屏幕、平板显示器、常规电视机或屏幕投影仪。除显示设备4291之外,计算机也可包括其它外围输出设备,如扬声器4297和打印机4296,它们通过输出外围接口4295连接。
计算机4210可以使用到一个或多个远程计算机,如远程计算机4280的逻辑连接在网络化环境中操作。远程计算机4280可以是个人计算机,并通常包括许多或所有以上相对于计算机4210所描述的元件,尽管在图42中仅示出了存储器存储设备4281。图42描述的逻辑连接包括局域网(LAN)4271和广域网(WAN)4273,但也可包括其它网络,诸如到城域网(MAN)、内联网或因特网的连接。
当在LAN网络环境中使用时,计算机4210通过网络接口或适配器4270连接至LAN 4271。当在WAN网络环境中使用时,计算机4210通常包括调制解调器4272或用于通过WAN 4273,如因特网建立通信的其它装置。调制解调器4272可以是内置或外置的,它通过网络接口4270或其它适当的机制连接至系统总线4221。调制解调器4272可以是电缆调制解调器、DSL调制解调器或其它宽带设备。在网络化环境中,相对于计算机4210所描述的程序模块或其部分可储存在远程存储器存储设备中。作为示例而非局限,图42示出远程应用程序4285驻留在存储器设备4281上。可以理解,示出的网络连接是示例性的,也可以使用在计算机之间建立通信链路的其它手段。
尽管未示出计算机4210的许多其它内部组件,但是本领域的普通技术人员将认识到,这些组件和互连是公知的。例如,在计算机4210内包括诸如电视调谐卡和网络接口卡等各种扩展卡是常规的。因此,关于计算机4210的内部构造的附加细节不需要在描述实现增量分页器的过程的示例性实施例时公开。
当计算机4210被开启或重启时,储存在ROM 4231中的BIOS 4233指示处理单元4220将操作系统或其必要的部分从硬盘驱动器4241加载到RAM4232中。一旦操作系统中被指定为操作系统4244的所复制部分被加载到RAM4232中,处理单元4220就执行该操作系统代码,并使得与操作系统4232的用户界面相关联的可视元素被显示在显示设备4291上。通常,当应用程序4245被用户打开时,从硬盘驱动器4241中读取程序代码和相关数据,并且将必要的部分复制到RAM 4232中,所复制的部分此处由参考标号4235来表示。
结论
尽管以对结构特征和/或方法动作专用的语言描述了示例性实施例,但是可以理解,所附权利要求书不一定限于以上所描述的具体特征或动作。相反,这些具体特征和动作是作为示例性实施例来公开的。