基于延迟更新的NO-UNDO REDO恢复
数据库管理系统 (DBMS) 中的延迟更新的概念是指将对磁盘上数据库的实际更新推迟到事务成功完成执行并到达提交点。
在事务执行期间,更新仅记录在日志和缓存缓冲区中。一旦事务到达其提交点并且日志强制写入磁盘,则将更新记录到数据库中。如果事务在到达提交点之前失败,则无需撤消任何操作,因为磁盘上的数据库保持不变。因此,日志中只需要REDO类型的日志条目,其中包含写入操作写入的项目的新值(AFIM)。由于在恢复期间无需撤消任何操作,因此不需要UNDO类型的日志条目。但是,这种方法仅适用于更改较少的短期事务,否则缓冲区空间可能不足以容纳事务更改直到提交点。
典型的延迟更新协议可以描述如下:
在事务到达其提交点之前,不允许修改磁盘上的数据库。
只有当所有REDO类型的日志条目都记录在日志中并且日志缓冲区强制写入磁盘时,事务才能到达其提交点。
需要注意的是,此协议的步骤2实际上重申了预写日志 (WAL) 协议。由于数据库在事务提交后才更新到磁盘,因此永远不需要撤消任何操作。相反,如果事务提交后但其所有更改在记录到磁盘上的数据库之前系统发生故障,则需要REDO操作。在这种情况下,在恢复过程中使用日志条目重做事务操作。
对于采用并发控制的多用户系统,并发控制和恢复的过程紧密交织在一起。在采用严格两阶段锁进行并发控制的系统中,对项目的锁保持有效,直到事务到达其提交点。只有在那之后,才能释放锁,确保严格和可串行化的调度。假设检查点条目包含在日志中,我们可以概述此场景的可能恢复算法,称为RDU_M(在多用户环境中使用延迟更新的恢复)。
过程 RDU_M(无撤销/重做,带检查点)
系统维护两个事务列表:自上次检查点以来已提交的事务T(提交列表)和活动事务T(活动列表)。该算法涉及对日志中记录的已提交事务的写入操作执行REDO操作,按照其写入顺序执行。
未提交的活动事务被视为有效取消,必须重新提交。
REDO过程定义如下。
过程 REDO (WRITE_OP)
重做write_item操作WRITE_OP需要检查其日志条目[write_item, T, X, new_value]并将数据库中项目X的值设置为new_value,它表示后映像 (AFIM)。
在下图中,给出了一个时间线来说明执行事务的潜在调度。在t1时刻,进行了检查点,表明事务T1已提交,而事务T3和T4尚未到达其提交点。在t2时刻,系统崩溃。在崩溃之前,T3和T2已提交,但T4和T5尚未提交。根据前面描述的RDU_M方法,无需重做事务T1或在t1时刻上次检查点之前提交的任何事务的write_item操作。但是,必须重做T2和T3的write_item操作,因为这两个事务都在上次检查点之后到达了其提交点。
重要的是要记住,在事务提交之前,日志会强制写入磁盘。在恢复过程中忽略事务T4和T5,因为在延迟更新协议下,它们的write_item操作未记录在磁盘上的数据库中。因此,这些事务被视为有效取消或回滚。
处理延迟更新中的已中止事务
为了提高NO-UNDO/REDO恢复算法的效率,我们可以通过认识到以下事实来优化该过程:如果自上次检查点以来,已提交的事务多次更新了数据项X,则在恢复期间仅从日志中REDO X的最后一次更新就足够了。这是因为之前的更新将被最后一次REDO操作覆盖。为了实现这种优化,我们遵循以下步骤:
从日志的末尾开始,在恢复过程中反向遍历它。
维护一个已重做项目的列表,最初为空。
当需要重做项目时,检查它是否已存在于已重做项目的列表中。
如果在列表中找到该项目,则无需再次重做它,因为它的最后一个值已恢复。
如果项目不在列表中,则执行REDO操作以根据相应的日志条目设置其值。
重做项目后,将其添加到已重做项目的列表中。
继续此过程,直到根据日志条目重做所有必要的项目。
通过避免对已恢复项目的冗余重做操作,这种优化减少了整体恢复时间和资源利用率。
优点和缺点
如果事务中止,无论原因是什么(例如死锁检测),它都可以简单地重新提交,因为它没有对磁盘上的数据库进行任何更改。但是,此处描述的方法具有一定的局限性和考虑因素。一个缺点是它限制了事务的并发执行,因为写锁定的项目在事务到达其提交点之前保持锁定状态。此外,它可能需要大量的缓冲区空间来保存所有更新的项目,直到事务提交为止。尽管存在这些限制,但该方法提供了两个主要优点:
事务在到达其提交点之前不会在磁盘上的数据库中记录任何更改,这意味着由于事务执行期间的失败而不会回滚它们。
事务永远不会读取未提交的事务写入的项目的 value,因为项目在事务到达其提交点之前保持锁定状态。因此,不会发生级联回滚。
数据结构
网络
关系数据库管理系统 (RDBMS)
操作系统
Java
iOS
HTML
CSS
Android
Python
C语言编程
C++
C#
MongoDB
MySQL
Javascript
PHP