我正在尝试使用System.IO.Log功能来构建可恢复的事务系统。我理解它是在Common Log File System之上实现的。
用于预写日志的常用ARIES方法涉及将日志记录序列号持久保存在日志以外的位置(例如,在被记录操作修改的数据库页面的标题中)。
有趣的是,CLFS 的文档说这样的序列号始终是 64 位整数。
然而,令人困惑的是,围绕这些SequenceNumber
s 的 .Net 包装器可以从 a 构造,byte[]
但不能从 a构造UInt64
。它的值也可以读作 abyte[]
,但不能读作 a UInt64
。检查 的实现SequenceNumber.GetBytes()
表明它实际上可以返回 8 或 16 字节的数组。
这提出了几个问题:
- 为什么 .Net 序列号与 CLFS 序列号的大小不同?
- 为什么 .Net 序列号的长度可变?
- 为什么需要 128 位来表示这样的序列号?看起来您会在用完 64 位地址空间(16 exbibytes,或大约 10^19 字节,如果您处理更长的字时更多)之前很好地截断日志?
- 如果日志序列号将表示为 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 标题字段而不会将标题或页面内容溢出到新页面,这两者都不是在一般情况下是可行的(因为您将检测到这种情况的点远不如您将获得有关如何执行此类恢复的信息的点抽象,如果您存储的数据结构甚至允许这种情况)。