2

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

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

有趣的是,CLFS 的文档说这样的序列号始终是 64 位整数

然而,令人困惑的是,围绕这些SequenceNumbers 的 .Net 包装器可以从 a 构造,byte[]但不能从 a构造UInt64。它的值也可以读作 abyte[],但不能读作 a UInt64。检查 的实现SequenceNumber.GetBytes()表明它实际上可以返回 8 或 16 字节的数组。

这提出了几个问题:

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

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

澄清

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

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

4

3 回答 3

4

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

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

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

于 2010-06-01T13:19:02.497 回答
3

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

于 2010-04-10T06:19:03.487 回答
1

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

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

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

于 2010-08-29T07:18:46.323 回答