Project: FoundationDB (App Definition and Development / Database)
File: How a commit is done in FDB.md

This doc describes how commit is done in FDB 6.3+. The commit path in FDB 6.3 and before is documented in . Legend: `alt` means alternative paths The texts in `[]` are conditions The texts above the arrow are messages. The diagrams are generated using https://sequencediagram.org. The source code of the diagrams are the `*.sequence` files. Before all RPCs mentioned below, the client would first verify if the commit proxies and GRV proxies are changed, by comparing the client information ID it holds to the ID the cluster coordinator holds. If they are different, the proxies are changed and the client will refresh the proxies list. The GRV Proxy sends a request to master to retrieve the current commit version. This version is the read version of the request. The commit proxy sends a request for commit version, with a request number. The request number is a monotonically increasing number per commit proxy. This ensures for each proxy, the master will process the requests in order. The master server waits until the request number is current. When the current request number is larger than the incoming request number If a commit version is already assigned to the incoming request number, return the commit version and the previous commit version. (i.e. `prevVersion`) Otherwise return `Never` Increase current commit version, return it back to the commit proxy. Only one process serves as master. Thus the commit version is unique for each cluster. The monotonically increasing commit version will ensure that each transaction is processed in a strict serial order. The commit proxy sends the transaction to the resolver. Resolver waits until its version reaches `prevVersion` Ensures all transactions having version smaller than this transaction are resolved. Detects conflicts for the given transaction: If there is no conflict, return `TransactionCommitted` as the status Any conflict, return `TransactionConflict` status If the read snapshot is not in MVCC, return `TransactionTooOld` status The proxy waits until the local batch number is current The proxy updates the metadata keys and attaches corresponding storage servers' tags to all mutations. The proxy then waits until the commit version is current, i.e. the proxy's committed version is catching up with the commit version of the batch and these two versions are within the MVCC window. The proxy pushes the commit data to TLogs. TLog waits the commit version to be current, then persists the commit. Wait until all* TLogs return the transaction result. The proxy updates the master with the committed version for next GRV request at the master. Reply the result to the client, base on the result from the resolver. `g_traceBatch` can be used for querying the transactions and commits. A typical query in the trace logs is: ``` Type=type Location=location ``` The format of `location` is, in general, `<sourcefilename>.<function/actor name>.<log information>`, e.g. ``` NativeAPI.getConsistentReadVersion.Before ``` means the `location` is at `NativeAPI.actor.cpp`, `ACTOR` `getConsistentReadVersion`, `Before` requesting the read version from GRV Proxy. Some example queries are: ``` Type=TransactionDebug Location=NativeAPI* ``` ``` LogGroup=loggroup Type=CommitDebug

``` In the following sections, <span style="color:green">green</span> tag indicates an attach; <span style="color:blue">blue</span> tag indicates an event that the location follows the format mentioned above, where only the `<log information>` is included; <span style="color:lightblue">light-blue</span> tag indicates an event that the location is not following the format, where the full location is included. All the `g_traceBatch` events are tabularized after the diagram. `contrib/commit_debug.py` can be used to visualize the commit

| Role | File name | Function/Actor | Trace | Type | Location | | | -- | | | | | | Client | NativeAPI | Transaction::getReadVersion | | | | | | | readVersionBatcher | | | | | | | getConsistentReadVersion | Before | TransactionDebug | | | GRVProxy | GrvProxyServer | queueGetReadVersionRequests | Before | TransactionDebug | | | | | transactionStarter | | | | | | | | AskLiveCommittedVersionFromMaster | TransactionDebug | | | | | getLiveCommittedVersion | confirmEpochLive | TransactionDebug | | | Master | MasterServer | serveLiveCommittedVersion | GetRawCommittedVersion | TransactionDebug | | | GRVProxy | GrvProxyServer | getLiveCommittedVersion | After | TransactionDebug | | | Client | NativeAPI | getConsistentReadVersion | After | TransactionDebug | | | Role | File name | Function/Actor | Trace | Name | Location | Notes | | | - | -- | | | | | | Client | NativeAPI | Transaction::get | | | | | | | | Transaction::getReadVersion | | | (Refer to GetReadVersion) | | | | | getKeyLocation | Before | TransactionDebug | | getKeyLocation is called by getValue, getKeyLocation actually calls getKeyLocation_internal | | | | | After | TransactionDebug | | | | | | getValue | | | | | | | | | Before | GetValueDebug | | | | Storage Server | StorageServer | serveGetValueRequests | received | GetValueDebug | | | | | | getValueQ | DoRead | GetValueDebug | | | | | | | AfterVersion | GetValueDebug | | | | | KeyValueStoreSQLite | KeyValueStoreSQLite::Reader::action | Before | GetValueDebug | | | | | | | After | GetValueDebug | | | | | StorageServer | | AfterRead | GetValueDebug | | | | Client | NativeAPI | getValue | After | GetValueDebug | | (When successful) | | | | | Error | GetValueDebug | | (When failure) | | Role | File name | Function/Actor | Trace | Name | Location | Notes | | | - | | -- | - | | | | Client | NativeAPI | Transaction::getRange | | | | | | | | Transaction::getReadVersion | | | (Refer to GetReadVersion) | | | | | getKeyLocation | Before | TransactionDebug | | getKeyLocation is called by getRange | | | | | After | TransactionDebug | | | | | | getRange | Before | TransactionDebug | | | | Storage Server | storageserver | getKeyValuesQ | Before | TransactionDebug | | | | | | | AfterVersion | TransactionDebug | | | | | | | AfterKeys | TransactionDebug | | | | | | | Send | TransactionDebug | | (When no keys found) | | | | | AfterReadRange | TransactionDebug | | (When found keys in this SS) | | Client | NativeAPI | getRange | After | TransactionDebug | | (When successful) | | | | | Error | TransactionDebug | | (When failure) | | Role | File name | Function/Actor | Trace | Type | Location | Notes | | - | - | -- | | - | | -- | | Client | NativeAPI | getRangeFallback | | | | | | | | getKey | | | GetKeyAttachID | | | | | | AfterVersion | GetKeyDebug | | | | | | | Before | GetKeyDebug | | | | | | | After | GetKeyDebug | | Success | | | | | Error | GetKeyDebug | | Error | | | | getReadVersion | | | | (Refer to GetReadVersion) |