···7777At some point a Timekeeper role was added to the database to write the current versionstamp into the meta keyspace every 10 seconds.
7878Those keys are used as a reverse lookup table (real time -> versionstamp) internally within the database (IIRC for something backup-related).
7979This is, frankly, a pretty good hint that something has gone off the rails.
8080+8181+## Another way
8282+8383+I want Hobbes to have versions that line up with real (wall clock) time,
8484+as this seems to be a useful property in practice.
8585+Obviously the time will never be perfect (wall clocks can be wrong),
8686+but Tigerbeetle in particular has shown that more can be done in this area.
8787+8888+Using wall clock time for versions is mostly trivial.
8989+Like FDB, we already use wall clocks to match the *progression* of time (1 version = 1 microsecond),
9090+so all that really needs to be done is to *start* a cluster at wall clock time (instead of zero)
9191+and ensure strict monotonicity across generations (no regression if clocks go backwards) for safety.
9292+9393+And, of course, we need to avoid the fast-forward.
9494+9595+### Avoiding fast-forward
9696+9797+As discussed earlier,
9898+there are two reasons for the fast-forward in FDB.
9999+100100+The first, with the Resolver, is easily fixed.
101101+The new generation has a known start version,
102102+and the Resolver (or the CommitBuffers) can reject transactions that started below that version.
103103+This trivially ensures that transactions do not span recoveries.
104104+105105+The second reason, with the Storage servers, is trickier.
106106+Storage servers do not participate directly in recovery,
107107+and there is no guarantee that they'll find out about a new generation before a client attempts a read with a read version from it.
108108+Since the generations' versions may overlap (because we don't fast-forward),
109109+a client might read uncommitted data that was meant to be thrown away.
110110+111111+However, there is actually another simple solution:
112112+we can accompany each read version with the generation of the transaction system that provided it.
113113+If the Storage server receives a read from a newer generation, it can trivially reject that read.