Currently, we persist all users catalog data in the stash. We would like to move all of that data to Persist. This will have the following benefits:
All user catalog data is stored in Persist.
The config collection is a subset of catalog data that can never be migrated. As a consequence, this
data can be read before the catalog is fully opened and can be used to bootstrap an environment. The
config collection has keys of type String
and values of type u64
. Booleans can be modeled using
this collection by storing a 0
for false
and 1
for true
. This proposal will add a key called
tombstone
, with a boolean value that indicates if a specific catalog backend is retired. A value
of false
means that the backend is not retired (i.e. is still in use) and a value of true
means
the backend is retired (i.e. is not still in use).
The catalog durably stores a fencing token called the epoch. All catalog writers and readers also store an in-memory epoch. When a new writer or reader connects to the catalog they store the previous epoch plus one in memory and persist this new value durably. Every time a reader or write performs a read or write, they compare their in-memory token with the persisted token, and if there's a difference, the operation fails. As a result, whenever a reader/write increments the epoch durably, they are effectively fencing out all previous readers/writers.
Opening a catalog involves the following two steps:
Below are the steps to migrate from the stash to persist.
true
, then we're done.true
.Below are the steps to rollback from persist to the stash.
false
or doesn't exist, then we're done.false
.NOTE: Steps (5) and (6) can be done as a single write as a performance optimization.
Below is a table describing all possible states of the stash tombstone and what they indicate about where the source of truth catalog data is located.
Stash Tombstone | Source of Truth | Explanation |
---|---|---|
None | Stash | Migration has never fully completed. |
Some(true) | Persist | Migration has completed successfully or rollback crashed before completing. |
Some(false) | Stash | Rollback has completed successfully or migration crashed before completing. |
Below is a state transition diagram that shows all possible states of the stash tombstone and how
the states transition. Each node has the value of the stash tombstone. Each edge indicates what
steps from the algorithm above triggers that specific state transition. Next to each node is either
Stash
if the stash is the source of truth, or Persist
if persist is the source of truth.
Below is a similar algorithm that uses two tombstone values, one in persist and one in the stash. Some may find that the individual states are slightly easier to reason about, but the state transitions are harder to reason about.
Below are the steps to migrate from the stash to persist.
true
.false
, then we're done.false
.NOTE: Steps (6) and (7) can be done as a single compare and append operation as a performance optimization.
Below are the steps to rollback from persist to the stash.
false
.true
or doesn't exist, then we're done.true
.Below is a table describing all possible states of (stash_tombstone, persist_tombstone) and what they indicate about where the source of truth catalog data is located.
Stash Tombstone | Persist Tombstone | Source of Truth | Explanation |
---|---|---|---|
None | _ | Stash | Migration has never been initiated. |
_ | None | Stash | Migration has never fully completed. |
Some(true) | Some(false) | Persist | Migration has completed successfully. |
Some(false) | Some(true) | Stash | Rollback has completed successfully. |
Some(true) | Some(true) | Stash | Migration crashed before completing. |
Some(false) | Some(false) | Persist | Rollback crashed before completing. |
Below is a state transition diagram that shows all possible states of
(stash_tombstone, persist_tombstone) and how the states transition. Each node has the format of
(stash_tombstone, persist_tombstone). Each edge indicates what steps from the algorithm above
triggers that specific state transition. Next to each node is either Stash
if the stash is the
source of truth, or Persist
if persist is the source of truth.