【问题标题】:Why do System.IO.Log SequenceNumbers have variable length?为什么 System.IO.Log 序列号具有可变长度?
【发布时间】:2010-04-10 05:58:27
【问题描述】:

我正在尝试使用System.IO.Log 功能来构建可恢复的事务系统。我理解它是在Common Log File System 之上实现的。

通常的ARIES 预写日志记录方法涉及将日志记录序列号保留在日志以外的位置(例如,在被记录操作修改的数据库页面的标题中)。

有趣的是,CLFS 的文档说sequence numbers are always 64-bit integers

然而,令人困惑的是,围绕 SequenceNumbers 的 .Net 包装器可以是 constructed from a byte[],但不能来自 UInt64。它的值也可以是read as a byte[],但不能是UInt64。检查SequenceNumber.GetBytes() 的实现表明它实际上可以返回8 或16 字节的数组。

这引发了几个问题:

  1. 为什么 .Net 序列号与 CLFS 序列号的大小不同?
  2. 为什么 .Net 序列号的长度可变?
  3. 为什么需要 128 位来表示这样的序列号?似乎您会在用完 64 位地址空间(16 exbibytes,或大约 10^19 字节,如果您处理更长的字时更多)之前很好地截断日志?
  4. 如果日志序列号将表示为 128 位整数,为什么不提供一种将它们序列化/反序列化为 UInt64s 对的方法,而不是为短暂的新 byte[] 带来相当无意义的堆分配s 每次你需要写/读一个?或者,为什么还要将SequenceNumber 设置为值类型呢?

将日志序列号的存储开销加倍似乎是一个奇怪的折衷,这样您就可以拥有超过一百万 TB 的未截断日志,所以我觉得我在这里遗漏了一些东西,或者可能是一些东西。如果有知情人士能指正我,我将不胜感激。

澄清

我同意 Damien 和 Andras 的说法。到目前为止,这些担忧是对 byte[] 返回类型最有可能的解释。但是在 CLFS 之上的当前实现,在检查反汇编时,它创建了 64 位 LSN 的代码路径和它创建 128 位 LSN 的代码路径。为什么?在 CLFS 之上使用 System.IO.Log 的客户端能否将 LSN 安全地存储在固定长度的 64 位字段中? 128位字段?任何固定长度的字段?

如果 LSN 可以是任意长度,那么它几乎是无用的,因为您需要在页面标题的某个位置有一个 LSN 字段来实现生理恢复。如果该字段是可变长度的,那么寻址页面的非标题部分的复杂性不会显着增加。如果对可变长度没有限制,那么您甚至无法确定页面上是否有空间来扩展 LSN 标题字段而不会将标题或页面内容溢出到新页面,这两者都不是在一般情况下是可行的(因为您将检测到这种情况的点远不如您将获得有关如何执行此类恢复的信息的点抽象,如果您存储的数据结构甚至允许这种情况)。

【问题讨论】:

    标签: .net transactions recovery


    【解决方案1】:

    最明显的原因是 UInt64 不符合 CLS,而 System.IO.Log 程序集明确标记为 CLSCompliant(true)(在反射器中打开)。

    而且由于平台将基础类型定义为 ULONGLONG,因此将结果强制转换为 Int64 是不安全的,因为一半的结果将是负数并且结果空间会环绕。

    因此,除了更改 CLS 规范以接受无符号整数之外,最好的解决方案是采用字节数组结果 - 正如 Damien 所建议的那样,如果未来版本的 windows 扩展它,它还具有额外的优势返回更多位。

    【讨论】:

    • Int64 的未经检查的强制转换将符合 CLS 且安全,但我同意可能会与负数混淆,并且有人可能认为比较 Int64 会得到与比较相同的结果它们代表的 LSN。
    • @Doug - 是的,我断言它不安全:我实际上的意思是它具有误导性并且不是好的做法;因此,他们对价值进行了额外的间接处理,这对我来说很有意义。如果是我,我可能会(错误地)牺牲 CLS 合规性来支持 UInt64!
    【解决方案2】:

    嗯,您的第一个链接提到了 IRecordSequence 接口的两个实现,其中只有一个是基于 CLFS 的。当然,未来也可能有其他的实现。因此,也许他们知道其他一些使用更长序列号的系统,并且不希望人们编写假定序列号始终为 64 位的代码。

    【讨论】:

    • 可以,但是接口是根据 SequenceNumber 值类型定义的,并且该类型的实现有两个 UInt64,而不是一个 byte[]。即使许多或大多数客户端希望将序列号保留在固定长度的字段中,它(在一定程度上)也适用于未来验证,但它不允许当前的实现使用超过 64 位。还有实现的问题,它(至少显然在检查 IL 时)有时甚至在 CLFS 之上创建 128 位(或至少 65 位实现为 128 位)值。
    【解决方案3】:

    我对可变长度 LSN 的个人直觉是,它并不意味着任何应用程序都假设它无法预测其 LSN 的大小(假设它没有改变它提供者)。至于真正的原因,我怀疑不联系比我更了解的人来推测对我没有帮助。

    只要我们可以肯定地说出任何关于未来的事情,我认为可以肯定地说,CLFS 的用户可以假设它的 LSN 在合理的时间内不会改变长度,而不会出现大量的流失。 Win32 API。 (我是作为一个在 CLFS 工作了几年的人说的。)

    我同意有很多应用程序在技术上不得不支持可变长度 LSN。

    【讨论】:

      猜你喜欢
      • 2019-03-18
      • 2019-04-17
      • 1970-01-01
      • 2023-01-04
      • 1970-01-01
      • 2022-08-03
      • 2021-09-25
      • 2011-11-27
      • 2016-11-09
      相关资源
      最近更新 更多