Vector Timestamps (TreadMarks)

This is with respect to TreadMarks. We care about where the/a lock has been throughout the system, so it can figure out what it needs to update. Perfect consistency relies on a universal “wall-clock time”1 which is prohibitvely expensive to maintain. Instead of global time, TM uses logical clocks to track only the specific events we care about.

Logical time advances only during lock acquires acq and releases rel. Every lock has a timestamp, called the logical clock, which is a monotonically increasing natural number. A vector timestamp is an array containing the logical clock for each node. If there are nodes, vector timestamp has length . Each entry is the logical clock for node , and on initialization, all entries are .

Time Stamp Comparison

Because each node maintains its own vector timestamp, these vectors can be mathematically compared in a partial order to determine the relative ordering of events. Consider two vector timestamps and . There are three cases:

  1. : This implies .
  2. : This implies .
  3. and are incomparable. The timestamps are mixed when neither is strongly greater than the other.
    • If there is only one lock, this cannot happen. Otherwise, it would imply that the lock was acquired by two different nodes at the same time, which is impossible (race condition).
    • If there are multiple locks, it can happen, only during execution of two independent locks. This is expected and not a problem, providing a partial ordering of events.

Example 1

Consider two nodes and that there is only one lock.

Init: [0, 0]
A acq: [1, 0]
A rel: [2, 0]
B acq: [2, 1]

Now suppose performs multiple acquires and releases, and we get the following vector timestamp:

[2, 17]

Example 2

Consider four nodes and that there are multiple locks. Suppose and acquire (different) locks at the same time, and then needs to talk to the lock manager (LM). In the middle of ‘s acquire, might have released. The vector timestamps might look like:

Initial: [0, 0, 0]
ABC: [0, 0, 0]
A,C acq -> A[1, 0, 0], B[0, 0, 0], C[0, 0, 1]
A rel -> A[2, 0, 0], B[0, 0, 0], C[0, 0, 1]

How can we compare and ? Here, and are incomparable because neither is strongly greater than the other. This undefined behavior of vector timestamps is actually a feature, as it lets LM know that ‘s acquire happened during ‘s acquire, and thus needs to update based on ‘s acquire, allowing LM to delay the update until the acquire.

The ability of undefined behavior gives an optimization opportunity. It allows the system to make more informed decisions about when to update locks and when to wait.

Footnotes

  1. Some kind of “all-knowing” time reference that is not practically achievable in a distributed system.”