为什么System.IO.Log SequenceNumbers有可变长度?

时间:2010-04-10 05:58:28

标签: .net transactions recovery

我正在尝试使用System.IO.Log功能构建可恢复的交易系统。我理解它是在Common Log File System

之上实现的

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

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

然而,令人困惑的是,SequenceNumber周围的.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位整数,为什么不提供一种方法来将它们序列化/反序列化为UInt64对,而不是毫无意义地为短期新的{{ {1}每次你需要写/读一个?或者,为什么还要为byte[]设置一个值类型呢?
  5. 将日志序列号的存储开销加倍,这似乎是一个奇怪的权衡,因此您可以拥有超过一百万TB的未截断日志,所以我觉得我在这里丢失了一些东西,或者可能是一些东西。如果有知情人士可以帮我直截了当,我会非常感激。

    澄清

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

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

3 个答案:

答案 0 :(得分:3)

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

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

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

答案 1 :(得分:2)

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

答案 2 :(得分:1)

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

只要我们能够肯定地说出未来的确定性,我认为可以肯定地说,CLFS的用户可以假设其LSN在一段合理的时间内不会改变其长度而没有大量的流失Win32 API。 (我说这是作为CLFS工作了几年的人。)

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