I don’t know of an article describing it offhand. The issue arises where each transaction occurs on a different node or set of nodes, and the causal link between them is external to the dbms. In this case, it’s possible for each transaction to independently commit without the necessary message exchanges to ensure their HLC based timestamps correspond with their causal order. In other words since the client doesn’t participate in the HLC scheme, it breaks the causal chain and can allow an HLC-based system to assign out of order timestamps.
This is hinted at in the HLC paper but it’s not very clear: Section 2 limits the definition of “happens before” to only apply to events which occur on the same node or after a message is received from another node.
Isn’t that just describing reintroducing waiting out the uncertainty window in order gain back external consistency? I’m not sure that ends up being substantially different from TrueTime.
Yeah, that's why I was asking. I've seen some various comments about the details of this but nothing definitive. I'm hoping when I have the mental bandwidth to sit down and go through the TLA proofs of HLC I'll fully grok it.
One immediate difference between TrueTime and HLC springs to mind though: TT knows the clock ambiguity when the timestamp was generated, HLC does not. So in practice I think TT may see much shorter wait intervals, than HLC which would have to conservative wait out the maximum clock drift estimate allowed.
A skim through the cdb source is consistent with this. It looks like when they hit a read/write conflict where the write has a non-zero logical component in it's HLC stamp, then they wait out any remaining portion of the ambiguity window. Since the max offset is around 400ms, that seems like it could hurt pretty bad under contended writes.
I think HLC would get more interesting if the stamps were extended with the ambiguity interval at stamp time.
This is hinted at in the HLC paper but it’s not very clear: Section 2 limits the definition of “happens before” to only apply to events which occur on the same node or after a message is received from another node.