Graft API
MetaStore
Section titled “MetaStore”snapshot(VolumeId, LSN)
Section titled “snapshot(VolumeId, LSN)”Returns Snapshot metadata for a particular LSN (or the latest if null). Does not include Segments.
pull_graft(VolumeId, LSN Range)
Section titled “pull_graft(VolumeId, LSN Range)”Retrieve the snapshot at the end of the given LSN range along with a Graft containing all changed indexes in the range. If the start of the range is Unbounded, it will be set to the last checkpoint.
pull_commits(VolumeId, LSN Range)
Section titled “pull_commits(VolumeId, LSN Range)”Retrieve all of the commits to the Volume in the provided LSN Range. If the start of the range is Unbounded, it will be set to the last checkpoint. Returns: graft.metastore.v1.PullSegmentsResponse
commit(VolumeId, ClientId, Snapshot LSN, page_count, segments)
Section titled “commit(VolumeId, ClientId, Snapshot LSN, page_count, segments)”Commit changes to a Volume if it is safe to do so. The provided Snapshot LSN is the snapshot the commit was based on. Returns the newly committed Snapshot on success.
The Commit handler is idempotent if the same ClientId tries to issue a duplicate commit. Currently the Metastore only compares the ClientId to detect duplicates. It’s up to the Client to ensure that it doesn’t submit two different commits at the same LSN. This may be improved via a checksum in the future.
PageStore
Section titled “PageStore”read_pages(Volume ID, LSN, graft)
Section titled “read_pages(Volume ID, LSN, graft)”First, updates our segment index if we haven’t seen this Volume ID/LSN before by querying the Metastore for new Segments.
Then selects a list of Segment candidates by querying the Segment index for all Segments that contain LSN’s up to the target LSN for the specific Volume ID and overlaps with the requested graft.
Finally, queries the index of each matching Segment, which may require downloading and caching the Segment from Object Storage. As the node finds the most recent matching LSN for each PageIdx, some of the Segment candidates may be skippable (if they no longer overlap with outstanding PageIdxs). Pages are sent back to the client as they are found in a stream. Each page is prefixed with a header containing it’s PageIdx.
If the Pagestore encounters missing Segments, it must update the Segment index. It’s possible that the client is querying a LSN which is older than the oldest checkpoint in which case we will fail the request.
Important: Segments with overlapping grafts and version ranges must be iterated in an order determined by the metastore. This is to handle the case that a single transaction wrote the same PageIdx multiple times at the same LSN.
write_pages(Volume ID, [(pageidx, page)]
Section titled “write_pages(Volume ID, [(pageidx, page)]”Writes a set of Pages for a Volume. Returns a list of new Segments: [(segment ID, graft)]
once they have been flushed to durable storage. Implementations should support streaming writes to the server to improve pipeline performance.
The writePages request will fail if the client submits the same PageIdx multiple times. This ensures that every segment generated by a request does not intersect.
Newly written segments may be cached on disk, but not added to the Segment index. This is because the pagestore doesn’t yet know if the Segments have been accepted by the Metastore, and additionally doesn’t know their assigned LSN.