我正在尝试使用System.IO.Log功能来构建可恢复的事务系统。我理解它将在Common Log File System之上实现。
通常的ARIES预写日志记录方法涉及在日志以外的位置保存日志记录序列号(例如,在记录的操作修改的数据库页的标题中)。
有趣的是,CLFS的文档说这样的sequence numbers are always 64-bit integers。
然而,令人困惑的是,围绕那些SequenceNumber
s的.Net包装器可能是constructed from a byte[]
但不是来自UInt64
。它的价值也可以是read as a byte[]
,但不是UInt64
。检查SequenceNumber.GetBytes()
的实现表明它实际上可以返回8或16字节的数组。
这引出了一些问题:
UInt64
s对,而不是每次需要写入/读取时毫无意义地为短期新byte[]
s产生堆分配一?或者,为什么要让SequenceNumber
成为一个值类型呢?将日志序列号的存储开销加倍,这似乎是一个奇怪的权衡,因此你可以拥有超过一百万兆字节的未截断日志,所以我觉得我在这里丢失了一些东西,或者可能是一些东西。如果有知情人士可以帮助我,我会非常感激。
澄清
我同意Damien和Andras所说的话。到目前为止,这些问题是对byte []返回类型最可能的解释。但是,在检查反汇编时,CLFS之上的当前实现具有创建64位LSN的代码路径和创建128位LSN的代码路径。为什么?并且在CLFS之上使用System.IO.Log的客户端是否可以将LSN安全地存储在固定长度的64位字段中? 128位字段?任何固定长度的字段?
如果LSN可以具有任意长度,那么它是无用的,因为您需要在页眉的某处使用LSN字段来实现生理逻辑恢复。如果字段具有可变长度,那么寻址页面的非标题部分的复杂性会有不小的增加。如果在可变长度上没有限制,那么您甚至无法确定页面上是否有空间来展开LSN标题字段而不将标题或页面内容溢出到新页面,这两者都不是在一般情况下是可行的(因为您将检测到这种情况的点远不如您将获得有关如何执行此类恢复的信息的那一点,如果您存储的数据结构甚至允许这种类型的东西)。
好吧,你的第一个链接提到了IRecordSequence接口的两个实现,其中只有一个是基于CLFS的接口。当然,也可能有其他未来的实施。因此,也许他们知道其他一些使用较长序列号的系统,并且不希望人们编写假定序列号始终为64位的代码。
最明显的原因是因为UInt64不符合CLS,而System.IO.Log程序集明确标记为CLSCompliant(true)(在反射器中打开)。
由于平台将底层类型定义为ULONGLONG,因此将结果强制转换为Int64是不安全的,因为一半的结果将是负数,结果空间将会回滚。
因此,除了将CLS规范更改为接受无符号整数之外,最好的解决方案是采用字节数组结果 - 正如Damien建议的那样,还有一个额外的优势,即未来版本的Windows应该将其扩展到返回更多位。
我对可变长度LSN的个人直觉是,它并不意味着任何应用程序都假设它无法预测其LSN的大小(假设它没有改变它的提供者)。至于实际原因,我怀疑如果不与那些比我更了解的人接触,我就不会有所帮助。
只要我们可以对未来有所确定,我认为可以肯定地说,CLFS的用户可以假设其LSN在一段合理的时间内不会改变其Win32 API中没有大量流失的时间。 (我说这是作为CLFS工作了几年的人。)
我同意有很多应用程序在技术上很难支持可变长度的LSN。