Why are System.IO.Log SequenceNumbers variable length?
I am trying to use System.IO.Log to create a recoverable transactional system. I understand that it will be implemented on top of the Common Log File System .
The usual ARIES approach to the write-to-write protocol involves persisting the sequence numbers of the log records in locations other than the log (for example, in a database page title changed by a logged action).
Interestingly, the documentation for CLFS states that such sequence numbers are always 64-bit integers .
It is confusing, however, that the .net wrapper around these SequenceNumber
can be built frombyte[]
, but not from UInt64
. This value can also be read asbyte[]
, but not as UInt64
. Checking the implementation SequenceNumber.GetBytes()
shows that it can actually return arrays of 8 or 16 bytes.
Several questions arise:
- Why are .Net sequence numbers different in size from CLFS sequence numbers?
- Why do .Net variable lengths change in length?
- Why do you need 128 bits to represent such a sequence number? It looks like you would truncate the log well before using a 64-bit address space (16 exbibytes or about 10 ^ 19 bytes if you are using longer words)?
- If the log ordinal numbers are going to be represented as 128-bit integers, why not provide a way to serialize / deserialize them as pairs
UInt64
instead of rather pointlessly popping up heap allocations for the short-lived newbyte[]
time you need to write / read? Alternatively, why specify a value type at allSequenceNumber
?
It seems like an odd tradeoff to double the overhead of storing the log numbers so you can have an unused log over a million terabytes long, so I feel like I'm missing something, or maybe a few things. I would be very grateful if someone from my acquaintances could put me straight.
Clarification
I agree with what Damien and Andras are saying. These problems are by far the most likely explanation for the byte [] return type. But the current implementation on top of CLFS has, on parse check, code paths where it creates 64-bit LSNs and code paths where it creates 128-bit LSNs. What for? And can a client using System.IO.Log over CLFS safely store LSN in a 64-bit fixed length field? 128 bit field? Any fixed length field?
This is next to useless if LSNs can be of arbitrary length, since physiological recovery requires an LSN field somewhere in the page header. If the field is variable in length, then there is a slight increase in complexity related to the non-title portion of the page. If there is no limit on the length of the variable, you cannot even be sure that you will have free space on the page to expand the LSN header field without spilling neither the title nor the content of the page into a new page, neither of which is viable in general case (since the point at which you find this condition is much less abstract than the point at which you have information on how to perform such a restore, if the data structure you store even allows something like this).
source to share
Ok, your first link mentions two implementations of the IRecordSequence interface, only one of which is CLFS-based. And of course there may be other future implementations as well. So perhaps they are aware of some other systems that use longer sequence numbers and do not want people to write code that assumes sequence numbers are always 64 bits.
source to share
The most obvious reason for this is that UInt64 is not CLS compliant, whereas System.IO.Log Assembly is clearly marked CLSCompliant (true) (opened in reflector).
And since the platform defines the base type to be ULONGLONG, it is unsafe to force the output to Int64 since half of the results will be negative and the result space will be wrapped.
So the best solution, besides changing the CLS spec to accept unsigned ints, was to accept the result of a byte array, which also has the added benefit, as Damien suggests, of future checking if a future version of windows expands it to return more bits.
source to share
My personal intuition around variable length LSNs is that it is not meant for any application to assume that it cannot predict the size of its LSN (given that it has not changed its provider). As far as the actual reason is concerned, I suspect that it would not be helpful for me to speculate without making contact with people who know better than me.
As far as we can ever say anything with certainty about the future, I think it's safe to say that CLFS users can assume that its LSN won't change in length in a reasonable amount of time without a lot of churn in its Win32 API. (I say this as someone who has worked at CLFS for several years.)
I agree that there are many applications where you technically suck to support variable length LSNs.
source to share