CLFS 日志序列号

在通用日志文件系统 (CLFS) 中,给定流中的每个日志记录都由 LSN) (日志序列号唯一标识。 将记录写入流时,会返回一个 LSN,该 LSN 标识该记录以供将来参考。

为特定流创建的 LSN 构成了严格递增的序列。 也就是说,分配给给定流中日志记录的 LSN 始终大于之前写入同一流的日志记录的 LSN。 以下函数可用于比较给定流中日志记录的 LSN。

ClfsLsnNull

ClfsLsnEqual

ClfsLsnGreater

ClfsLsnLess

CLFS_LSN_NULL常量和CLFS_LSN_INVALID常量是所有有效 LSN 的下限和上限。 任何有效的 LSN 都大于或等于CLFS_LSN_NULL。 此外,任何有效的 LSN 都严格小于 CLFS_LSN_INVALID。 请注意,CLFS_LSN_NULL是有效的 LSN,而 CLFS_LSN_INVALID 不是有效的 LSN。 即便如此,也可以使用上一个列表中的函数将CLFS_LSN_INVALID与其他 LSN 进行比较。

对于每个流,CLFS 都会跟踪两个特殊 LSN:基本 LSN 和最后一个 LSN。 此外,每个日志记录都有两个特殊的 LSN, (上一个 LSN 和撤消下一个 LSN) ,可用于创建相关日志记录链。 以下部分详细介绍了这些特殊的 LSN。

基本 LSN

当客户端写入流中的第一条记录时,CLFS 将基本 LSN 设置为该第一条记录的 LSN。 在客户端更改基本 LSN 之前,基本 LSN 保持不变。 当流的客户端不再需要流中某个点之前的记录时,它们可以通过调用 ClfsAdvanceLogBaseClfsWriteRestartArea 来更新基本 LSN。 例如,如果客户端不再需要前五条日志记录,则可以将基本 LSN 设置为第六条记录的 LSN。

“最后一个 LSN”

当客户端将记录写入流时,CLFS 会调整最后一个 LSN,使其始终是写入的最后一条记录的 LSN。 如果客户端在流中的某个点后不再需要记录,它们可以通过调用 ClfsSetEndOfLog 更新最后一个 LSN。 例如,如果客户端不再需要第 10 条记录后写入任何记录,则可以通过将最后一个 LSN 设置为第十条记录的 LSN 来截断流。

流的活动部分

流的 活动部分 是流的部分,该部分以基 LSN 指向的记录开始,以最后一个 LSN 指向的记录结束。 下图演示了基本 LSN 和最后一个 LSN 如何描述流的活动部分。

说明 clfs 流的活动部分的示意图。

注意 如果流具有存档尾部,则流的活动部分从基本 LSN 或存档尾部指向的记录开始,以较小者为准。 有关存档的详细信息,请参阅 CLFS 存档支持

上一个 LSN

假设两个活动数据库事务 (事务 A 和事务 B) 同时将记录写入同一个流。 事务 A 每次写入记录时,都会将该记录的上一个 LSN 设置为事务 A 写入的上一日志记录的 LSN。这构成了属于事务 A 的日志记录链,可以按相反的顺序遍历。 链以事务 A 写入的第一条日志记录结尾,该记录将以前的 LSN 设置为 CLFS_LSN_INVALID。 同样,事务 B 通过设置它写入的每个日志记录的先前 LSN 来创建自己的日志记录链。

下图中的箭头演示了日志记录的上一个 LSN 如何指向属于特定事务的链中的上一条记录。

说明以前的 lsn 指针的示意图。

撤消下一个 LSN

假设事务对易失性内存中的数据对象进行了五次更新,回滚第四次和第五次更新,然后进行第六次更新。 事务进行更新时,会写入日志记录 1、2、3、4、5、5、5'、4'和 6。 日志记录 1 到 5 描述了更新 1 到 5 所做的更改。 记录 5' 描述了在更新 5 回滚期间所做的更改,记录 4' 描述了在回滚更新 4 期间所做的更改。 最后,记录 6 描述了更新 6 所做的更改。 请注意,数字 1、2、3、4、5、5'、4'和 6 不是日志记录的 LSN;它们只是用于为本讨论目的命名日志记录的数字。

描述回滚的日志记录 5' 和 4'称为补偿日志记录 (CLR) 。 事务将每个 CLR 的撤消下一个 LSN 设置为由日志记录的事务) 写入的记录中的前置 (,该记录的更新刚刚回滚 (撤消) 。 在此示例中,记录 5' 的撤消下一个 LSN 是记录 4 的 LSN,记录 4' 的撤消下一个 LSN 是记录 3 的 LSN。

普通日志记录 (不是 CLR) 的日志记录,将其撤消下一个 LSN 设置为事务写入的上一日志记录。 也就是说,对于普通记录,撤消下一个 LSN 和以前的 LSN 是相同的。

现在假设存在系统故障,在重启恢复期间,必须回滚整个事务。 恢复代码读取日志记录 6。 记录 6 中的数据指示记录 6 是普通记录 (不是 CLR) ,因此恢复代码回滚更新 6。 然后,恢复代码检查记录 6 的撤消下一个 LSN,并发现它指向记录 4'。 记录 4' 中的数据指示它是 CLR,因此恢复代码不会回滚 update 4'。 相反,它会检查记录 4' 的撤消下一个 LSN,并发现它指向记录 3。 记录 3 不是 CLR,因此恢复代码回滚更新 3。 汇报 5 和 4 在恢复期间不会回滚,因为它们已在普通向前处理期间回滚。 最后,恢复代码回滚更新 2 和更新 1。

下图中的箭头说明了撤消下一个 LSN 如何提供一种机制,恢复代码可用于跳过已回滚更新的记录。

说明上一个 lsn 和撤消下一个 lsn 指针的示意图。