mirror of
https://github.com/talent-plan/tinykv.git
synced 2024-12-27 13:20:24 +08:00
5e089a2cd1
Signed-off-by: Connor <zbk602423539@gmail.com> Co-authored-by: Nick Cameron <nrc@ncameron.org> Co-authored-by: linning <linningde25@gmail.com> Co-authored-by: YangKeao <keao.yang@yahoo.com> Co-authored-by: andylokandy <andylokandy@hotmail.com> Co-authored-by: Iosmanthus Teng <myosmanthustree@gmail.com>
41 lines
2.9 KiB
Go
41 lines
2.9 KiB
Go
package transaction
|
|
|
|
// The transaction package implements TinyKV's 'transaction' layer. This takes incoming requests from the kv/server/server.go
|
|
// as input and turns them into reads and writes of the underlying key/value store (defined by Storage in kv/storage/storage.go).
|
|
// The storage engine handles communicating with other nodes and writing data to disk. The transaction layer must
|
|
// translate high-level TinyKV commands into low-level raw key/value commands and ensure that processing of commands do
|
|
// not interfere with processing other commands.
|
|
//
|
|
// Note that there are two kinds of transactions in play: TinySQL transactions are collaborative between TinyKV and its
|
|
// client (e.g., TinySQL). They are implemented using multiple TinyKV requests and ensure that multiple SQL commands can
|
|
// be executed atomically. There are also mvcc transactions which are an implementation detail of this
|
|
// layer in TinyKV (represented by MvccTxn in kv/transaction/mvcc/transaction.go). These ensure that a *single* request
|
|
// is executed atomically.
|
|
//
|
|
// *Locks* are used to implement TinySQL transactions. Setting or checking a lock in a TinySQL transaction is lowered to
|
|
// writing to the underlying store.
|
|
//
|
|
// *Latches* are used to implement mvcc transactions and are not visible to the client. They are stored outside the
|
|
// underlying storage (or equivalently, you can think of every key having its own latch). See the latches package for details.
|
|
//
|
|
// Within the `mvcc` package, `Lock` and `Write` provide abstractions for lowering locks and writes into simple keys and values.
|
|
//
|
|
// ## Encoding user key/values
|
|
//
|
|
// The mvcc strategy is essentially to store all data (committed and uncommitted) at every point in time. So for example, if we store
|
|
// a value for a key, then store another value (a logical overwrite) at a later time, both values are preserved in the underlying
|
|
// storage.
|
|
//
|
|
// This is implemented by encoding user keys with their timestamps (the starting timestamp of the transaction in which they are
|
|
// written) to make an encoded key (see codec.go). The `default` CF is a mapping from encoded keys to their values.
|
|
//
|
|
// Locking a key means writing into the `lock` CF. In this CF, we use the user key (i.e., not the encoded key so that a key is locked
|
|
// for all timestamps). The value in the `lock` CF consists of the 'primary key' for the transaction, the kind of lock (for 'put',
|
|
// 'delete', or 'rollback'), the start timestamp of the transaction, and the lock's ttl (time to live). See lock.go for the
|
|
// implementation.
|
|
//
|
|
// The status of values is stored in the `write` CF. Here we map keys encoded with their commit timestamps (i.e., the time at which a
|
|
// a transaction is committed) to a value containing the transaction's starting timestamp, and the kind of write ('put', 'delete', or
|
|
// 'rollback'). Note that for transactions which are rolled back, the start timestamp is used for the commit timestamp in the encoded
|
|
// key.
|