import "github.com/cockroachdb/cockroach/pkg/internal/client"
Package client and its KV API have been deprecated for external usage. Please use a postgres-compatible SQL driver (e.g. github.com/lib/pq). For more details, see http://www.cockroachlabs.com/blog/sql-in-cockroachdb-mapping-table-data-to-key-value-storage/.
Package client provides clients for accessing the various externally-facing Cockroach database endpoints.
The DB client is a fully-featured client of Cockroach's key-value database. It provides a simple, synchronous interface well-suited to parallel updates and queries.
The simplest way to use the client is through the Run method. Run synchronously invokes the call, fills in the reply and returns an error. The example below shows a get and a put.
db, err := client.Open("rpcs://root@localhost:26257") if err != nil { log.Fatal(err) } if err := db.Put("a", "hello"); err != nil { log.Fatal(err) } if gr, err := db.Get("a"); err != nil { log.Fatal(err) } else { log.Printf("%s", gr.ValueBytes()) // "hello" }
The API is synchronous, but accommodates efficient parallel updates and queries using Batch objects. An arbitrary number of calls may be added to a Batch which is executed using DB.Run. Note however that the individual calls within a batch are not guaranteed to have atomic semantics. A transaction must be used to guarantee atomicity. A simple example of using a Batch which does two scans in parallel and then sends a sequence of puts in parallel:
db, err := client.Open("rpcs://root@localhost:26257") if err != nil { log.Fatal(err) } b1 := &client.Batch{} b1.Scan("a", "c\x00", 1000) b1.Scan("x", "z\x00", 1000) // Run sends both scans in parallel and returns the first error or nil. if err := db.Run(b1); err != nil { log.Fatal(err) } acResult := b1.Results[0] xzResult := b1.Results[1] // Append maximum value from "a"-"c" to all values from "x"-"z". max := []byte(nil) for _, row := range acResult.Rows { if bytes.Compare(max, row.ValueBytes()) < 0 { max = row.ValueBytes() } } b2 := &client.Batch{} for _, row := range xzResult.Rows { b2.Put(row.Key, bytes.Join([][]byte{row.ValueBytes(), max}, []byte(nil))) } // Run all puts for parallel execution. if err := db.Run(b2); err != nil { log.Fatal(err) }
Transactions are supported through the DB.Txn() method, which takes a retryable function, itself composed of the same simple mix of API calls typical of a non-transactional operation. Within the context of the Txn() call, all method invocations are transparently given necessary transactional details, and conflicts are handled with backoff/retry loops and transaction restarts as necessary. An example of using transactions with parallel writes:
db, err := client.Open("rpcs://root@localhost:26257") if err != nil { log.Fatal(err) } err := db.Txn(func(ctx context.Context, txn *client.Txn) error { b := txn.NewBatch() for i := 0; i < 100; i++ { key := fmt.Sprintf("testkey-%02d", i) b.Put(key, "test value") } // Note that the Txn client is flushed automatically when this function // returns success (i.e. nil). Calling CommitInBatch explicitly can // sometimes reduce the number of RPCs. return txn.CommitInBatch(ctx, b) }) if err != nil { log.Fatal(err) }
Note that with Cockroach's lock-free transactions, clients should expect retries as a matter of course. This is why the transaction functionality is exposed through a retryable function. The retryable function should have no side effects which are not idempotent.
Transactions should endeavor to use batches to perform multiple operations in a single RPC. In addition to the reduced number of RPCs to the server, this allows writes to the same range to be batched together. In cases where the entire transaction affects only a single range, transactions can commit in a single round trip.
batch.go db.go doc.go lease.go lease.pb.go range_lookup.go sender.go txn.go util.go
DefaultLeaseDuration is the duration a lease will be acquired for if no duration was specified in a LeaseManager's options. Exported for testing purposes.
var ( ErrInvalidLengthLease = fmt.Errorf("proto: negative length found during unmarshaling") ErrIntOverflowLease = fmt.Errorf("proto: integer overflow") )
ChangeReplicasCanMixAddAndRemoveContext convinces (*client.DB).AdminChangeReplicas that the caller is aware that 19.1 nodes don't know how to handle requests that mix additions and removals; 19.2+ binaries understand this due to the work done in the context of atomic replication changes. If 19.1 nodes received such a request they'd mistake the removals for additions.
In effect users of the RPC need to check the cluster version which in the past has been a brittle pattern, so this time the DB disallows the new behavior unless it can determine (via the ctx) that the caller went through this method and is thus aware of the intricacies.
See https://github.com/cockroachdb/cockroach/pull/39611.
TODO(tbg): remove in 20.1.
IncrementValRetryable increments a key's value by a specified amount and returns the new value.
It performs the increment as a retryable non-transactional increment. The key might be incremented multiple times because of the retries.
func RangeLookup( ctx context.Context, sender Sender, key roachpb.Key, rc roachpb.ReadConsistencyType, prefetchNum int64, prefetchReverse bool, ) (rs, preRs []roachpb.RangeDescriptor, err error)
RangeLookup is used to look up RangeDescriptors - a RangeDescriptor is a metadata structure which describes the key range and replica locations of a distinct range in the cluster. They map the logical keyspace in cockroach to its physical replicas, allowing a node to send requests for a certain key to the replicas that contain that key.
RangeDescriptors are stored as values in the cockroach cluster's key-value store. However, they are always stored using special "Range Metadata keys", which are "ordinary" keys with a special prefix prepended. The Range Metadata Key for an ordinary key can be generated with the `keys.RangeMetaKey(key)` function. The RangeDescriptor for the range which contains a given key can be retrieved by generating its Range Metadata Key and scanning from the key forwards until the first RangeDescriptor is found. This is what this function does with the provided key.
Note that the Range Metadata Key sent as the StartKey of the lookup scan is NOT the key at which the desired RangeDescriptor is stored. Instead, this method returns the RangeDescriptor stored at the _lowest_ existing key which is _greater_ than the given key. The returned RangeDescriptor will thus contain the ordinary key which was provided to this function.
The "Range Metadata Key" for a range is built by appending the end key of the range to the respective meta prefix.
It is often useful to think of Cockroach's ranges as existing in a three level tree:
[/meta1/,/meta1/max) <-- always one range, gossipped, start here! | ----------------------- | | [/meta2/,/meta2/m) [/meta2/m,/meta2/max) | | --------- --------- | | | | [a,g) [g,m) [m,s) [s,max) <- user data
In this analogy, each node (range) contains a number of RangeDescriptors, and these descriptors act as pointers to the location of its children. So given a key we want to find, we can use the tree structure to find it, starting at the tree's root (meta1). But starting at the root, how do we know which pointer to follow? This is where RangeMetaKey comes into play - it turns a key in one range into a meta key in its parent range. Then, when looking at its parent range, we know that the descriptor we want is the first descriptor to the right of this meta key in the parent's ordered set of keys.
Let's look at a few examples that demonstrate how RangeLookup performs this task of finding a user RangeDescriptors from cached meta2 descriptors:
Ex. 1:
Meta2 Ranges: [/meta2/a, /meta2/z) User Ranges: [a, f) [f, p), [p, z) 1.a: RangeLookup(key=f) In this case, we want to look up the range descriptor for the range [f, p) because "f" is in that range. Remember that this descriptor will be stored at "/meta2/p". Of course, when we're performing the RangeLookup, we don't actually know what the bounds of this range are or where exactly it's stored (that's what we're looking up!), so all we have to go off of is the lookup key. So, we first determine the meta key for the lookup key using RangeMetaKey, which is simply "/meta2/f". We then construct the scan bounds for this key using MetaScanBounds. This scan bound will be [/meta2/f.Next(),/meta2/max). The reason that this scan doesn't start at "/meta2/f" is because if this key is the start key of a range (like it is in this example!), the previous range descriptor will be stored at that key. We then issue a forward ScanRequest over this range. Since we're assuming we already cached the meta2 range that contains this span of keys, we send the request directly to that range's replica (if we didn't have this cached, the process would recurse to lookup the meta2 range descriptor). We then find that the first KV pair we see during the scan is at "/meta2/p". This is our desired range descriptor. 1.b: RangeLookup(key=m) This case is similar. We construct a scan for this key "m" from [/meta2/m.Next(),/meta2/max) and everything works the same as before. 1.b: RangeLookup(key=p) Here, we're looking for the descriptor for the range [p, z), because key "p" is included in that range, but not [f, p). We scan with bounds of [/meta2/p.Next(),/meta2/max) and everything works as expected.
Ex. 2:
Meta2 Ranges: [/meta2/a, /meta2/m) [/meta2/m, /meta2/z) User Ranges: [a, f) [f, p), [p, z) 2.a: RangeLookup(key=n) In this case, we want to look up the range descriptor for the range [f, p) because "n" is in that range. Remember that this descriptor will be stored at "/meta2/p", which in this case is on the second meta2 range. So, we construct the scan bounds of [/meta2/n.Next(),/meta2/max), send this scan to the second meta2 range, and find that the first descriptor found is the desired descriptor. 2.b: RangeLookup(key=g) This is where things get a little tricky. As usual, we construct scan bounds of [/meta2/g.Next(),/meta2/max). However, this scan will be routed to the first meta2 range. It will scan forward and notice that no descriptors are stored between [/meta2/g.Next(),/meta2/m). We then rely on DistSender to continue this scan onto the next meta2 range since the result from the first meta2 range will be empty. Once on the next meta2 range, we'll find the desired descriptor at "/meta2/p".
Ex. 3:
Meta2 Ranges: [/meta2/a, /meta2/m) [/meta2/m, /meta2/z) User Ranges: [a, f) [f, m), [m,s) [p, z) 3.a: RangeLookup(key=g) This is a little confusing, but actually behaves the exact same way at 2.b. Notice that the descriptor for [f, m) is actually stored on the second meta2 range! So the lookup scan will start on the first meta2 range and continue onto the second before finding the desired descriptor at /meta2/m. This is an unfortunate result of us storing RangeDescriptors at RangeMetaKey(desc.EndKey) instead of RangeMetaKey(desc.StartKey) even though our ranges are [inclusive,exclusive). Still everything works if we let DistSender do its job when scanning over the meta2 range. See #16266 and #17565 for further discussion. Notably, it is not possible to pick meta2 boundaries such that we will never run into this issue. The only way to avoid this completely would be to store RangeDescriptors at RangeMetaKey(desc.StartKey) and only allow meta2 split boundaries at RangeMetaKey(existingSplitBoundary)
Lookups for range metadata keys usually want to perform reads at the READ_UNCOMMITTED read consistency level read in order to observe intents as well. However, some callers need a consistent result; both are supported be specifying the ReadConsistencyType. If the lookup is consistent, the Sender provided should be a TxnCoordSender.
This method has an important optimization if the prefetchNum arg is larger than 0: instead of just returning the request RangeDescriptor, it also returns a slice of additional range descriptors immediately consecutive to the desired RangeDescriptor. This is intended to serve as a sort of caching pre-fetch, so that nodes can aggressively cache RangeDescriptors which are likely to be desired by their current workload. The prefetchReverse flag specifies whether descriptors are prefetched in descending or ascending order.
func SendWrapped( ctx context.Context, sender Sender, args roachpb.Request, ) (roachpb.Response, *roachpb.Error)
SendWrapped is identical to SendWrappedWith with a zero header. TODO(tschottdorf): should move this to testutils and merge with other helpers which are used, for example, in `storage`.
func SendWrappedWith( ctx context.Context, sender Sender, h roachpb.Header, args roachpb.Request, ) (roachpb.Response, *roachpb.Error)
SendWrappedWith is a convenience function which wraps the request in a batch and sends it via the provided Sender and headers. It returns the unwrapped response or an error. It's valid to pass a `nil` context; an empty one is used in that case.
func TestingIsRangeLookup(ba roachpb.BatchRequest) bool
TestingIsRangeLookup returns if the provided BatchRequest looks like a single RangeLookup scan. It can return false positives and should only be used in tests.
TestingIsRangeLookupRequest returns if the provided Request looks like a single RangeLookup scan. It can return false positives and should only be used in tests.
type AutoCommitError struct {
// contains filtered or unexported fields
}
AutoCommitError wraps a non-retryable error coming from auto-commit.
func (e *AutoCommitError) Error() string
type Batch struct { // Results contains an entry for each operation added to the batch. The order // of the results matches the order the operations were added to the // batch. For example: // // b := db.NewBatch() // b.Put("a", "1") // b.Put("b", "2") // _ = db.Run(b) // // string(b.Results[0].Rows[0].Key) == "a" // // string(b.Results[1].Rows[0].Key) == "b" Results []Result // The Header which will be used to send the resulting BatchRequest. // To be modified directly. Header roachpb.Header // contains filtered or unexported fields }
Batch provides for the parallel execution of a number of database operations. Operations are added to the Batch and then the Batch is executed via either DB.Run, Txn.Run or Txn.Commit.
TODO(pmattis): Allow a timestamp to be specified which is applied to all operations within the batch.
AddRawRequest adds the specified requests to the batch. No responses will be allocated for them, and using any of the non-raw operations will result in an error when running the batch.
CPut conditionally sets the value for a key if the existing value is equal to expValue. To conditionally set a value only if there is no existing entry pass nil for expValue. Note that this must be an interface{}(nil), not a typed nil value (e.g. []byte(nil)).
A new result will be appended to the batch which will contain a single row and Result.Err will indicate success or failure.
key can be either a byte slice or a string. value can be any key type, a protoutil.Message or any Go primitive type (bool, int, etc).
CPutAllowingIfNotExists is like CPut except it also allows the Put when the existing entry does not exist -- i.e. it succeeds if there is no existing entry or the existing entry has the expected value.
CPutDeprecated conditionally sets the value for a key if the existing value is equal to expValue. To conditionally set a value only if there is no existing entry pass nil for expValue. Note that this must be an interface{}(nil), not a typed nil value (e.g. []byte(nil)).
A new result will be appended to the batch which will contain a single row and Result.Err will indicate success or failure.
key can be either a byte slice or a string. value can be any key type, a protoutil.Message or any Go primitive type (bool, int, etc).
Del deletes one or more keys.
A new result will be appended to the batch and each key will have a corresponding row in the returned Result.
key can be either a byte slice or a string.
DelRange deletes the rows between begin (inclusive) and end (exclusive).
A new result will be appended to the batch which will contain 0 rows and Result.Err will indicate success or failure.
key can be either a byte slice or a string.
Get retrieves the value for a key. A new result will be appended to the batch which will contain a single row.
r, err := db.Get("a") // string(r.Rows[0].Key) == "a"
key can be either a byte slice or a string.
Inc increments the integer value at key. If the key does not exist it will be created with an initial value of 0 which will then be incremented. If the key exists but was set using Put or CPut an error will be returned.
A new result will be appended to the batch which will contain a single row and Result.Err will indicate success or failure.
key can be either a byte slice or a string.
InitPut sets the first value for a key to value. An ConditionFailedError is reported if a value already exists for the key and it's not equal to the value passed in. If failOnTombstones is set to true, tombstones will return a ConditionFailedError just like a mismatched value.
key can be either a byte slice or a string. value can be any key type, a protoutil.Message or any Go primitive type (bool, int, etc). It is illegal to set value to nil.
MustPErr returns the structured error resulting from a failed execution of the batch, asserting that that error is non-nil.
Put sets the value for a key.
A new result will be appended to the batch which will contain a single row and Result.Err will indicate success or failure.
key can be either a byte slice or a string. value can be any key type, a protoutil.Message or any Go primitive type (bool, int, etc).
PutInline sets the value for a key, but does not maintain multi-version values. The most recent value is always overwritten. Inline values cannot be mutated transactionally and should be used with caution.
A new result will be appended to the batch which will contain a single row and Result.Err will indicate success or failure.
key can be either a byte slice or a string. value can be any key type, a protoutil.Message or any Go primitive type (bool, int, etc).
func (b *Batch) RawResponse() *roachpb.BatchResponse
RawResponse returns the BatchResponse which was the result of a successful execution of the batch, and nil otherwise.
ReverseScan retrieves the rows between begin (inclusive) and end (exclusive) in descending order.
A new result will be appended to the batch which will contain "rows" (each "row" is a key/value pair) and Result.Err will indicate success or failure.
key can be either a byte slice or a string.
Scan retrieves the key/values between begin (inclusive) and end (exclusive) in ascending order.
A new result will be appended to the batch which will contain "rows" (each row is a key/value pair) and Result.Err will indicate success or failure.
key can be either a byte slice or a string.
type CrossRangeTxnWrapperSender struct {
// contains filtered or unexported fields
}
CrossRangeTxnWrapperSender is a Sender whose purpose is to wrap non-transactional requests that span ranges into a transaction so they can execute atomically.
TODO(andrei, bdarnell): This is a wart. Our semantics are that batches are atomic, but there's only historical reason for that. We should disallow non-transactional batches and scans, forcing people to use transactions instead. And then this Sender can go away.
func (s *CrossRangeTxnWrapperSender) Send( ctx context.Context, ba roachpb.BatchRequest, ) (*roachpb.BatchResponse, *roachpb.Error)
Send implements the Sender interface.
func (s *CrossRangeTxnWrapperSender) Wrapped() Sender
Wrapped returns the wrapped sender.
type DB struct { log.AmbientContext // contains filtered or unexported fields }
DB is a database handle to a single cockroach cluster. A DB is safe for concurrent use by multiple goroutines.
func NewDB(actx log.AmbientContext, factory TxnSenderFactory, clock *hlc.Clock) *DB
NewDB returns a new DB.
func NewDBWithContext( actx log.AmbientContext, factory TxnSenderFactory, clock *hlc.Clock, ctx DBContext, ) *DB
NewDBWithContext returns a new DB with the given parameters.
func (db *DB) AddSSTable( ctx context.Context, begin, end interface{}, data []byte, disallowShadowing bool, stats *enginepb.MVCCStats, ingestAsWrites bool, ) error
AddSSTable links a file into the RocksDB log-structured merge-tree. Existing data in the range is cleared.
func (db *DB) AdminChangeReplicas( ctx context.Context, key interface{}, expDesc roachpb.RangeDescriptor, chgs []roachpb.ReplicationChange, ) (*roachpb.RangeDescriptor, error)
AdminChangeReplicas adds or removes a set of replicas for a range.
AdminMerge merges the range containing key and the subsequent range. After the merge operation is complete, the range containing key will contain all of the key/value pairs of the subsequent range and the subsequent range will no longer exist. Neither range may contain learner replicas, if one does, an error is returned.
key can be either a byte slice or a string.
func (db *DB) AdminRelocateRange( ctx context.Context, key interface{}, targets []roachpb.ReplicationTarget, ) error
AdminRelocateRange relocates the replicas for a range onto the specified list of stores.
func (db *DB) AdminSplit( ctx context.Context, spanKey, splitKey interface{}, expirationTime hlc.Timestamp, ) error
AdminSplit splits the range at splitkey.
spanKey is a key within the range that should be split, and splitKey is the key at which that range should be split. splitKey is not used exactly as provided--it is first mutated by keys.EnsureSafeSplitKey. Accounting for this mutation sometimes requires constructing a key that falls in a different range, hence the separation between spanKey and splitKey. See #16008 for details, and #16344 for the tracking issue to clean this mess up properly.
expirationTime is the timestamp when the split expires and is eligible for automatic merging by the merge queue. To specify that a split should immediately be eligible for automatic merging, set expirationTime to hlc.Timestamp{} (I.E. the zero timestamp). To specify that a split should never be eligible, set expirationTime to hlc.MaxTimestamp.
The keys can be either byte slices or a strings.
func (db *DB) AdminTransferLease( ctx context.Context, key interface{}, target roachpb.StoreID, ) error
AdminTransferLease transfers the lease for the range containing key to the specified target. The target replica for the lease transfer must be one of the existing replicas of the range.
key can be either a byte slice or a string.
When this method returns, it's guaranteed that the old lease holder has applied the new lease, but that's about it. It's not guaranteed that the new lease holder has applied it (so it might not know immediately that it is the new lease holder).
AdminUnsplit removes the sticky bit of the range specified by splitKey.
splitKey is the start key of the range whose sticky bit should be removed.
If splitKey is not the start key of a range, then this method will throw an error. If the range specified by splitKey does not have a sticky bit set, then this method will not throw an error and is a no-op.
CPut conditionally sets the value for a key if the existing value is equal to expValue. To conditionally set a value only if there is no existing entry pass nil for expValue. Note that this must be an interface{}(nil), not a typed nil value (e.g. []byte(nil)).
Returns an error if the existing value is not equal to expValue.
key can be either a byte slice or a string. value can be any key type, a protoutil.Message or any Go primitive type (bool, int, etc).
Clock returns the DB's hlc.Clock.
Del deletes one or more keys.
key can be either a byte slice or a string.
DelRange deletes the rows between begin (inclusive) and end (exclusive).
TODO(pmattis): Perhaps the result should return which rows were deleted.
key can be either a byte slice or a string.
Get retrieves the value for a key, returning the retrieved key/value or an error. It is not considered an error for the key not to exist.
r, err := db.Get("a") // string(r.Key) == "a"
key can be either a byte slice or a string.
func (db *DB) GetFactory() TxnSenderFactory
GetFactory returns the DB's TxnSenderFactory.
GetProto retrieves the value for a key and decodes the result as a proto message. If the key doesn't exist, the proto will simply be reset.
key can be either a byte slice or a string.
func (db *DB) GetProtoTs( ctx context.Context, key interface{}, msg protoutil.Message, ) (hlc.Timestamp, error)
GetProtoTs retrieves the value for a key and decodes the result as a proto message. It additionally returns the timestamp at which the key was read. If the key doesn't exist, the proto will simply be reset and a zero timestamp will be returned. A zero timestamp will also be returned if unmarshaling fails.
key can be either a byte slice or a string.
Inc increments the integer value at key. If the key does not exist it will be created with an initial value of 0 which will then be incremented. If the key exists but was set using Put or CPut an error will be returned.
key can be either a byte slice or a string.
InitPut sets the first value for a key to value. A ConditionFailedError is reported if a value already exists for the key and it's not equal to the value passed in. If failOnTombstones is set to true, tombstones count as mismatched values and will cause a ConditionFailedError.
key can be either a byte slice or a string. value can be any key type, a protoutil.Message or any Go primitive type (bool, int, etc). It is illegal to set value to nil.
NewTxn creates a new RootTxn.
NonTransactionalSender returns a Sender that can be used for sending non-transactional requests. The Sender is capable of transparently wrapping non-transactional requests that span ranges in transactions.
The Sender returned should not be used for sending transactional requests - it bypasses the TxnCoordSender. Use db.Txn() or db.NewTxn() for transactions.
Put sets the value for a key.
key can be either a byte slice or a string. value can be any key type, a protoutil.Message or any Go primitive type (bool, int, etc).
PutInline sets the value for a key, but does not maintain multi-version values. The most recent value is always overwritten. Inline values cannot be mutated transactionally and should be used with caution.
key can be either a byte slice or a string. value can be any key type, a protoutil.Message or any Go primitive type (bool, int, etc).
func (db *DB) ReverseScan( ctx context.Context, begin, end interface{}, maxRows int64, ) ([]KeyValue, error)
ReverseScan retrieves the rows between begin (inclusive) and end (exclusive) in descending order.
The returned []KeyValue will contain up to maxRows elements.
key can be either a byte slice or a string.
Run executes the operations queued up within a batch. Before executing any of the operations the batch is first checked to see if there were any errors during its construction (e.g. failure to marshal a proto message).
The operations within a batch are run in parallel and the order is non-deterministic. It is an unspecified behavior to modify and retrieve the same key within a batch.
Upon completion, Batch.Results will contain the results for each operation. The order of the results matches the order the operations were added to the batch.
Scan retrieves the rows between begin (inclusive) and end (exclusive) in ascending order.
The returned []KeyValue will contain up to maxRows elements.
key can be either a byte slice or a string.
func (db *DB) SplitAndScatter( ctx context.Context, key roachpb.Key, expirationTime hlc.Timestamp, ) error
SplitAndScatter is a helper that wraps AdminSplit + AdminScatter.
Txn executes retryable in the context of a distributed transaction. The transaction is automatically aborted if retryable returns any error aside from recoverable internal errors, and is automatically committed otherwise. The retryable function should have no side effects which could cause problems in the event it must be run more than once.
WriteBatch applies the operations encoded in a BatchRepr, which is the serialized form of a RocksDB Batch. The command cannot span Ranges and must be run on an empty keyrange.
type DBContext struct { // UserPriority is the default user priority to set on API calls. If // userPriority is set to any value except 1 in call arguments, this // value is ignored. UserPriority roachpb.UserPriority // NodeID provides the node ID for setting the gateway node and avoiding // clock uncertainty for root transactions started at the gateway. NodeID *base.NodeIDContainer // Stopper is used for async tasks. Stopper *stop.Stopper }
DBContext contains configuration parameters for DB.
DefaultDBContext returns (a copy of) the default options for NewDBWithContext.
KeyValue represents a single key/value pair. This is similar to roachpb.KeyValue except that the value may be nil. The timestamp in the value will be populated with the MVCC timestamp at which this value was read if this struct was produced by a GetRequest or ScanRequest which uses the KEY_VALUES ScanFormat. Values created from a ScanRequest which uses the BATCH_RESPONSE ScanFormat will contain a zero Timestamp.
Exists returns true iff the value exists.
PrettyValue returns a human-readable version of the value as a string.
ValueBytes returns the value as a byte slice. This method will panic if the value's type is not a byte slice.
ValueInt returns the value decoded as an int64. This method will panic if the value cannot be decoded as an int64.
ValueProto parses the byte slice value into msg.
type Lease struct {
// contains filtered or unexported fields
}
Lease contains the state of a lease on a particular key.
type LeaseManager struct {
// contains filtered or unexported fields
}
LeaseManager provides functionality for acquiring and managing leases via the kv api.
func NewLeaseManager(db *DB, clock *hlc.Clock, options LeaseManagerOptions) *LeaseManager
NewLeaseManager allocates a new LeaseManager.
AcquireLease attempts to grab a lease on the provided key. Returns a non-nil lease object if it was successful, or an error if it failed to acquire the lease for any reason.
NB: Acquiring a non-expired lease is allowed if this LeaseManager's clientID matches the lease owner's ID. This behavior allows a process to re-grab leases without having to wait if it restarts and uses the same ID.
ExtendLease attempts to push the expiration time of the lease farther out into the future.
ReleaseLease attempts to release the given lease so that another process can grab it.
func (m *LeaseManager) TimeRemaining(l *Lease) time.Duration
TimeRemaining returns the amount of time left on the given lease.
type LeaseManagerOptions struct { // ClientID must be unique to this LeaseManager instance. ClientID string LeaseDuration time.Duration }
LeaseManagerOptions are used to configure a new LeaseManager.
type LeaseNotAvailableError struct {
// contains filtered or unexported fields
}
LeaseNotAvailableError indicates that the lease the caller attempted to acquire is currently held by a different client.
func (e *LeaseNotAvailableError) Error() string
type LeaseVal struct { // An opaque string that should be unique per client to identify which client // owns the lease. Owner string `protobuf:"bytes,1,opt,name=owner" json:"owner"` // The expiration time of the lease. Expiration hlc.Timestamp `protobuf:"bytes,2,opt,name=expiration" json:"expiration"` }
type MockTransactionalSender struct {
// contains filtered or unexported fields
}
MockTransactionalSender allows a function to be used as a TxnSender.
func NewMockTransactionalSender( f func( context.Context, *roachpb.Transaction, roachpb.BatchRequest, ) (*roachpb.BatchResponse, *roachpb.Error), txn *roachpb.Transaction, ) *MockTransactionalSender
NewMockTransactionalSender creates a MockTransactionalSender. The passed in txn is cloned.
func (m *MockTransactionalSender) AnchorOnSystemConfigRange() error
AnchorOnSystemConfigRange is part of the TxnSender interface.
func (m *MockTransactionalSender) AugmentMeta(context.Context, roachpb.TxnCoordMeta)
AugmentMeta is part of the TxnSender interface.
func (m *MockTransactionalSender) CommitTimestamp() hlc.Timestamp
CommitTimestamp is part of the TxnSender interface.
func (m *MockTransactionalSender) CommitTimestampFixed() bool
CommitTimestampFixed is part of the TxnSender interface.
func (m *MockTransactionalSender) DisablePipelining() error
DisablePipelining is part of the client.TxnSender interface.
func (m *MockTransactionalSender) Epoch() enginepb.TxnEpoch
Epoch is part of the TxnSender interface.
func (m *MockTransactionalSender) GetMeta( context.Context, TxnStatusOpt, ) (roachpb.TxnCoordMeta, error)
GetMeta is part of the TxnSender interface.
func (m *MockTransactionalSender) IsSerializablePushAndRefreshNotPossible() bool
IsSerializablePushAndRefreshNotPossible is part of the TxnSender interface.
func (m *MockTransactionalSender) ManualRestart( ctx context.Context, pri roachpb.UserPriority, ts hlc.Timestamp, )
ManualRestart is part of the TxnSender interface.
func (m *MockTransactionalSender) ReadTimestamp() hlc.Timestamp
ReadTimestamp is part of the TxnSender interface.
func (m *MockTransactionalSender) Send( ctx context.Context, ba roachpb.BatchRequest, ) (*roachpb.BatchResponse, *roachpb.Error)
Send is part of the TxnSender interface.
func (m *MockTransactionalSender) SerializeTxn() *roachpb.Transaction
SerializeTxn is part of the TxnSender interface.
func (m *MockTransactionalSender) SetDebugName(name string)
SetDebugName is part of the TxnSender interface.
SetFixedTimestamp is part of the TxnSender interface.
func (m *MockTransactionalSender) SetUserPriority(pri roachpb.UserPriority) error
SetUserPriority is part of the TxnSender interface.
func (m *MockTransactionalSender) TxnStatus() roachpb.TransactionStatus
TxnStatus is part of the TxnSender interface.
func (m *MockTransactionalSender) UpdateStateOnRemoteRetryableErr( ctx context.Context, pErr *roachpb.Error, ) *roachpb.Error
UpdateStateOnRemoteRetryableErr is part of the TxnSender interface.
type MockTxnSenderFactory struct {
// contains filtered or unexported fields
}
MockTxnSenderFactory is a TxnSenderFactory producing MockTxnSenders.
func MakeMockTxnSenderFactory( senderFunc func( context.Context, *roachpb.Transaction, roachpb.BatchRequest, ) (*roachpb.BatchResponse, *roachpb.Error), ) MockTxnSenderFactory
MakeMockTxnSenderFactory creates a MockTxnSenderFactory from a sender function that receives the transaction in addition to the request. The function is responsible for putting the txn inside the batch, if needed.
func (f MockTxnSenderFactory) NonTransactionalSender() Sender
NonTransactionalSender is part of TxnSenderFactory.
func (f MockTxnSenderFactory) TransactionalSender( _ TxnType, coordMeta roachpb.TxnCoordMeta, _ roachpb.UserPriority, ) TxnSender
TransactionalSender is part of TxnSenderFactory.
type NonTransactionalFactoryFunc SenderFunc
NonTransactionalFactoryFunc is a TxnSenderFactory that cannot, in fact, create any transactional senders, only non-transactional ones.
func (f NonTransactionalFactoryFunc) NonTransactionalSender() Sender
NonTransactionalSender is part of the TxnSenderFactory.
func (f NonTransactionalFactoryFunc) TransactionalSender( _ TxnType, _ roachpb.TxnCoordMeta, _ roachpb.UserPriority, ) TxnSender
TransactionalSender is part of the TxnSenderFactory.
type Result struct { // Err contains any error encountered when performing the operation. Err error // Rows contains the key/value pairs for the operation. The number of rows // returned varies by operation. For Get, Put, CPut, Inc and Del the number // of rows returned is the number of keys operated on. For Scan the number of // rows returned is the number or rows matching the scan capped by the // maxRows parameter and other options. For DelRange Rows is nil. Rows []KeyValue // Keys is set by some operations instead of returning the rows themselves. Keys []roachpb.Key // ResumeSpan is the the span to be used on the next operation in a // sequence of operations. It is returned whenever an operation over a // span of keys is bounded and the operation returns before completely // running over the span. It allows the operation to be called again with // a new shorter span of keys. A nil span is set when the operation has // successfully completed running through the span. ResumeSpan *roachpb.Span // When ResumeSpan is populated, this specifies the reason why the operation // wasn't completed and needs to be resumed. ResumeReason roachpb.ResponseHeader_ResumeReason // RangeInfos contains information about the replicas that produced this // result. // This is only populated if Err == nil and if ReturnRangeInfo has been set on // the request. RangeInfos []roachpb.RangeInfo // contains filtered or unexported fields }
Result holds the result for a single DB or Txn operation (e.g. Get, Put, etc).
ResumeSpanAsValue returns the resume span as a value if one is set, or an empty span if one is not set.
type Sender interface { // Send sends a batch for evaluation. // The contract about whether both a response and an error can be returned // varies between layers. // // The caller retains ownership of all the memory referenced by the // BatchRequest; the callee is not allowed to hold on to any parts of it past // after it returns from the call (this is so that the client module can // allocate requests from a pool and reuse them). For example, the DistSender // makes sure that, if there are concurrent requests, it waits for all of them // before returning, even in error cases. // // Once the request reaches the `transport` module, anothern restriction // applies (particularly relevant for the case when the node that the // transport is talking to is local, and so there's not gRPC // marshaling/unmarshaling): // - the callee has to treat everything inside the BatchRequest as // read-only. This is so that the client module retains the right to pass // pointers into its internals, like for example the Transaction. This // wouldn't work if the server would be allowed to change the Transaction // willy-nilly. // TODO(andrei): The client does not currently use this last guarantee; it // clones the txn for every request. Given that a client.Txn can be used // concurrently, in order for the client to take advantage of this, it would // need to switch to a copy-on-write scheme so that its updates to the txn do // not race with the server reading it. We should do this to avoid the cloning // allocations. And to be frank, it'd be a good idea for the // BatchRequest/Response to generally stop carrying transactions; the requests // usually only need a txn id and some timestamp. The responses would ideally // contain a list of targeted instructions about what the client should // update, as opposed to a full txn that the client is expected to diff with // its copy and apply all the updates. Send(context.Context, roachpb.BatchRequest) (*roachpb.BatchResponse, *roachpb.Error) }
Sender is implemented by modules throughout the crdb stack, on both the "client" and the "server", involved in passing along and ultimately evaluating requests (batches). The interface is now considered regrettable because it's too narrow and at times leaky. Notable implementors: client.Txn, kv.TxnCoordSender, storage.Node, storage.Store, storage.Replica.
func Wrap(sender Sender, f func(roachpb.BatchRequest) roachpb.BatchRequest) Sender
Wrap returns a Sender which applies the given function before delegating to the supplied Sender.
type SenderFunc func(context.Context, roachpb.BatchRequest) (*roachpb.BatchResponse, *roachpb.Error)
SenderFunc is an adapter to allow the use of ordinary functions as Senders.
func (f SenderFunc) Send( ctx context.Context, ba roachpb.BatchRequest, ) (*roachpb.BatchResponse, *roachpb.Error)
Send calls f(ctx, c).
type Txn struct {
// contains filtered or unexported fields
}
Txn is an in-progress distributed database transaction. A Txn is safe for concurrent use by multiple goroutines.
NewTxn returns a new txn. The typ parameter specifies whether this transaction is the top level (root), or one of potentially many distributed transactions (leaf).
If the transaction is used to send any operations, CommitOrCleanup() or CleanupOnError() should eventually be called to commit/rollback the transaction (including stopping the heartbeat loop).
gatewayNodeID: If != 0, this is the ID of the node on whose behalf this
transaction is running. Normally this is the current node, but in the case of Txns created on remote nodes by DistSQL this will be the gateway. If 0 is passed, then no value is going to be filled in the batches sent through this txn. This will have the effect that the DistSender will fill in the batch with the current node's ID. If the gatewayNodeID is set and this is a root transaction, we optimize away any clock uncertainty for our own node, as our clock is accessible.
See also db.NewTxn().
func NewTxnWithCoordMeta( ctx context.Context, db *DB, gatewayNodeID roachpb.NodeID, typ TxnType, meta roachpb.TxnCoordMeta, ) *Txn
NewTxnWithCoordMeta is like NewTxn, except it returns a new txn with the provided TxnCoordMeta. This allows a client.Txn to be created with an already initialized proto and TxnCoordSender.
func NewTxnWithProto( ctx context.Context, db *DB, gatewayNodeID roachpb.NodeID, typ TxnType, proto roachpb.Transaction, ) *Txn
NewTxnWithProto is like NewTxn, except it returns a new txn with the provided Transaction proto. This allows a client.Txn to be created with an already initialized proto.
AddCommitTrigger adds a closure to be executed on successful commit of the transaction.
AugmentTxnCoordMeta augments this transaction's TxnCoordMeta information with the supplied meta. For use with GetTxnCoordMeta().
CPut conditionally sets the value for a key if the existing value is equal to expValue. To conditionally set a value only if there is no existing entry pass nil for expValue. Note that this must be an interface{}(nil), not a typed nil value (e.g. []byte(nil)).
Returns an error if the existing value is not equal to expValue.
key can be either a byte slice or a string. value can be any key type, a protoutil.Message or any Go primitive type (bool, int, etc).
CleanupOnError cleans up the transaction as a result of an error.
Commit is the same as CommitOrCleanup but will not attempt to clean up on failure. This can be used when the caller is prepared to do proper cleanup.
CommitInBatch executes the operations queued up within a batch and commits the transaction. Explicitly committing a transaction is optional, but more efficient than relying on the implicit commit performed when the transaction function returns without error. The batch must be created by this transaction. If the command completes successfully, the txn is considered finalized. On error, no attempt is made to clean up the (possibly still pending) transaction.
CommitOrCleanup sends an EndTransactionRequest with Commit=true. If that fails, an attempt to rollback is made. txn should not be used to send any more commands after this call.
CommitTimestamp returns the transaction's start timestamp. The start timestamp can get pushed but the use of this method will guarantee that if a timestamp push is needed the commit will fail with a retryable error.
DB returns a transaction's DB.
DebugName returns the debug name associated with the transaction.
Del deletes one or more keys.
key can be either a byte slice or a string.
DelRange deletes the rows between begin (inclusive) and end (exclusive).
The returned Result will contain 0 rows and Result.Err will indicate success or failure.
key can be either a byte slice or a string.
DisablePipelining instructs the transaction not to pipeline requests. It should rarely be necessary to call this method. It is only recommended for transactions that need extremely precise control over the request ordering, like the transaction that merges ranges together.
DisablePipelining must be called before any operations are performed on the transaction.
Epoch exports the txn's epoch.
GenerateForcedRetryableError returns a TransactionRetryWithProtoRefreshError that will cause the txn to be retried.
The transaction's epoch is bumped, simulating to an extent what the TxnCoordSender does on retriable errors. The transaction's timestamp is only bumped to the extent that txn.ReadTimestamp is racheted up to txn.Timestamp. TODO(andrei): This method should take in an up-to-date timestamp, but unfortunately its callers don't currently have that handy.
Get retrieves the value for a key, returning the retrieved key/value or an error. It is not considered an error for the key to not exist.
r, err := db.Get("a") // string(r.Key) == "a"
key can be either a byte slice or a string.
GetProto retrieves the value for a key and decodes the result as a proto message. If the key doesn't exist, the proto will simply be reset.
key can be either a byte slice or a string.
func (txn *Txn) GetProtoTs( ctx context.Context, key interface{}, msg protoutil.Message, ) (hlc.Timestamp, error)
GetProtoTs retrieves the value for a key and decodes the result as a proto message. It additionally returns the timestamp at which the key was read. If the key doesn't exist, the proto will simply be reset and a zero timestamp will be returned. A zero timestamp will also be returned if unmarshaling fails.
key can be either a byte slice or a string.
GetTxnCoordMeta returns the TxnCoordMeta information for this transaction for use with AugmentTxnCoordMeta(), when combining the impact of multiple distributed transaction coordinators that are all operating on the same transaction.
GetTxnCoordMetaOrRejectClient is like GetTxnCoordMeta except, if the transaction is already aborted or otherwise in a final state, it returns an error. If the transaction is aborted, the error will be a retryable one, and the transaction will have been prepared for another transaction attempt (so, on retryable errors, it acts like Send()).
ID returns the current ID of the transaction.
Inc increments the integer value at key. If the key does not exist it will be created with an initial value of 0 which will then be incremented. If the key exists but was set using Put or CPut an error will be returned.
The returned Result will contain a single row and Result.Err will indicate success or failure.
key can be either a byte slice or a string.
InitPut sets the first value for a key to value. An error is reported if a value already exists for the key and it's not equal to the value passed in. If failOnTombstones is set to true, tombstones count as mismatched values and will cause a ConditionFailedError.
key can be either a byte slice or a string. value can be any key type, a protoutil.Message or any Go primitive type (bool, int, etc). It is illegal to set value to nil.
func (txn *Txn) InternalSetPriority(priority enginepb.TxnPriority)
InternalSetPriority sets the transaction priority. It is intended for internal (testing) use only.
IsCommitted returns true if the transaction has the committed status.
func (txn *Txn) IsRetryableErrMeantForTxn( retryErr roachpb.TransactionRetryWithProtoRefreshError, ) bool
IsRetryableErrMeantForTxn returns true if err is a retryable error meant to restart this client transaction.
IsSerializablePushAndRefreshNotPossible returns true if the transaction is serializable, its timestamp has been pushed and there's no chance that refreshing the read spans will succeed later (thus allowing the transaction to commit and not be restarted). Used to detect whether the txn is guaranteed to get a retriable error later.
Note that this method allows for false negatives: sometimes the client only figures out that it's been pushed when it sends an EndTransaction - i.e. it's possible for the txn to have been pushed asynchoronously by some other operation (usually, but not exclusively, by a high-priority txn with conflicting writes).
func (txn *Txn) Iterate( ctx context.Context, begin, end interface{}, pageSize int, f func([]KeyValue) error, ) error
Iterate performs a paginated scan and applying the function f to every page. The semantics of retrieval and ordering are the same as for Scan. Note that Txn auto-retries the transaction if necessary. Hence, the paginated data must not be used for side-effects before the txn has committed.
ManualRestart bumps the transactions epoch, and can upgrade the timestamp. An uninitialized timestamp can be passed to leave the timestamp alone.
Used by the SQL layer which sometimes knows that a transaction will not be able to commit and prefers to restart early. It is also used after synchronizing concurrent actors using a txn when a retryable error is seen. TODO(andrei): this second use should go away once we move to a TxnAttempt model.
NewBatch creates and returns a new empty batch object for use with the Txn.
PrepareForRetry needs to be called before an retry to perform some book-keeping.
TODO(andrei): I think this is called in the wrong place. See #18170.
Put sets the value for a key
key can be either a byte slice or a string. value can be any key type, a protoutil.Message or any Go primitive type (bool, int, etc).
ReadTimestamp returns the transaction's current read timestamp. Note a transaction can be internally pushed forward in time before committing so this is not guaranteed to be the commit timestamp. Use CommitTimestamp() when needed.
func (txn *Txn) ReverseScan( ctx context.Context, begin, end interface{}, maxRows int64, ) ([]KeyValue, error)
ReverseScan retrieves the rows between begin (inclusive) and end (exclusive) in descending order.
The returned []KeyValue will contain up to maxRows elements (or all results when zero is supplied).
key can be either a byte slice or a string.
Rollback sends an EndTransactionRequest with Commit=false. txn is considered finalized and cannot be used to send any more commands.
Run executes the operations queued up within a batch. Before executing any of the operations the batch is first checked to see if there were any errors during its construction (e.g. failure to marshal a proto message).
The operations within a batch are run in parallel and the order is non-deterministic. It is an unspecified behavior to modify and retrieve the same key within a batch.
Upon completion, Batch.Results will contain the results for each operation. The order of the results matches the order the operations were added to the batch.
func (txn *Txn) Scan( ctx context.Context, begin, end interface{}, maxRows int64, ) ([]KeyValue, error)
Scan retrieves the rows between begin (inclusive) and end (exclusive) in ascending order.
The returned []KeyValue will contain up to maxRows elements (or all results when zero is supplied).
key can be either a byte slice or a string.
func (txn *Txn) Send( ctx context.Context, ba roachpb.BatchRequest, ) (*roachpb.BatchResponse, *roachpb.Error)
Send runs the specified calls synchronously in a single batch and returns any errors. If the transaction is read-only or has already been successfully committed or aborted, a potential trailing EndTransaction call is silently dropped, allowing the caller to always commit or clean-up explicitly even when that may not be required (or even erroneous). Returns (nil, nil) for an empty batch.
Sender returns a transaction's TxnSender.
func (txn *Txn) Serialize() *roachpb.Transaction
Serialize returns a clone of the transaction's current proto. This is a nuclear option; generally client code shouldn't deal with protos. However, this is used by DistSQL for sending the transaction over the wire when it creates flows.
SetDebugName sets the debug name associated with the transaction which will appear in log files and the web UI.
SetFixedTimestamp makes the transaction run in an unusual way, at a "fixed timestamp": Timestamp and RefreshedTimestamp are set to ts, there's no clock uncertainty, and the txn's deadline is set to ts such that the transaction can't be pushed to a different timestamp.
This is used to support historical queries (AS OF SYSTEM TIME queries and backups). This method must be called on every transaction retry (but note that retries should be rare for read-only queries with no clock uncertainty).
SetSystemConfigTrigger sets the system db trigger to true on this transaction. This will impact the EndTransactionRequest.
func (txn *Txn) SetUserPriority(userPriority roachpb.UserPriority) error
SetUserPriority sets the transaction's user priority. Transactions default to normal user priority. The user priority must be set before any operations are performed on the transaction.
Type returns the transaction's type.
UpdateDeadlineMaybe sets the transactions deadline to the lower of the current one (if any) and the passed value.
The deadline cannot be lower than txn.ReadTimestamp.
UpdateStateOnRemoteRetryableErr updates the txn in response to an error encountered when running a request through the txn. Returns a TransactionRetryWithProtoRefreshError on success or another error on failure.
func (txn *Txn) UserPriority() roachpb.UserPriority
UserPriority returns the transaction's user priority.
type TxnSender interface { Sender // AnchorOnSystemConfigRange ensures that the transaction record, if/when it // will be created, will be created on the system config range. This is useful // because some commit triggers only work when the EndTransaction is evaluated // on that range. // // An error is returned if the transaction's key has already been set by // anything other than a previous call to this function (i.e. if the // transaction already performed any writes). // It is allowed to call this method multiple times. AnchorOnSystemConfigRange() error // GetMeta retrieves a copy of the TxnCoordMeta, which can be sent from root // to leaf transactions or the other way around. Can be combined via // AugmentMeta(). // // If AnyTxnStatus is passed, then this function never returns errors. GetMeta(context.Context, TxnStatusOpt) (roachpb.TxnCoordMeta, error) // AugmentMeta combines the TxnCoordMeta from another distributed // TxnSender which is part of the same transaction. AugmentMeta(ctx context.Context, meta roachpb.TxnCoordMeta) // SetUserPriority sets the txn's priority. SetUserPriority(roachpb.UserPriority) error // SetDebugName sets the txn's debug name. SetDebugName(name string) // TxnStatus exports the txn's status. TxnStatus() roachpb.TransactionStatus // SetFixedTimestamp makes the transaction run in an unusual way, at a "fixed // timestamp": Timestamp and ReadTimestamp are set to ts, there's no clock // uncertainty, and the txn's deadline is set to ts such that the transaction // can't be pushed to a different timestamp. // // This is used to support historical queries (AS OF SYSTEM TIME queries and // backups). This method must be called on every transaction retry (but note // that retries should be rare for read-only queries with no clock uncertainty). SetFixedTimestamp(ctx context.Context, ts hlc.Timestamp) // ManualRestart bumps the transactions epoch, and can upgrade the timestamp // and priority. // An uninitialized timestamp can be passed to leave the timestamp alone. // // Used by the SQL layer which sometimes knows that a transaction will not be // able to commit and prefers to restart early. // It is also used after synchronizing concurrent actors using a txn when a // retryable error is seen. // TODO(andrei): this second use should go away once we move to a TxnAttempt // model. ManualRestart(context.Context, roachpb.UserPriority, hlc.Timestamp) // UpdateStateOnRemoteRetryableErr updates the txn in response to an error // encountered when running a request through the txn. UpdateStateOnRemoteRetryableErr(context.Context, *roachpb.Error) *roachpb.Error // DisablePipelining instructs the TxnSender not to pipeline requests. It // should rarely be necessary to call this method. It is only recommended for // transactions that need extremely precise control over the request ordering, // like the transaction that merges ranges together. DisablePipelining() error // ReadTimestamp returns the transaction's current read timestamp. // Note a transaction can be internally pushed forward in time before // committing so this is not guaranteed to be the commit timestamp. // Use CommitTimestamp() when needed. ReadTimestamp() hlc.Timestamp // CommitTimestamp returns the transaction's start timestamp. // The start timestamp can get pushed but the use of this // method will guarantee that the caller of this method sees // the push and thus calls this method again to receive the new // timestamp. CommitTimestamp() hlc.Timestamp // CommitTimestampFixed returns true if the commit timestamp has // been fixed to the start timestamp and cannot be pushed forward. CommitTimestampFixed() bool // IsSerializablePushAndRefreshNotPossible returns true if the transaction is // serializable, its timestamp has been pushed and there's no chance that // refreshing the read spans will succeed later (thus allowing the transaction // to commit and not be restarted). Used to detect whether the txn is // guaranteed to get a retriable error later. // // Note that this method allows for false negatives: sometimes the client only // figures out that it's been pushed when it sends an EndTransaction - i.e. // it's possible for the txn to have been pushed asynchoronously by some other // operation (usually, but not exclusively, by a high-priority txn with // conflicting writes). IsSerializablePushAndRefreshNotPossible() bool // Epoch returns the txn's epoch. Epoch() enginepb.TxnEpoch // SerializeTxn returns a clone of the transaction's current proto. // This is a nuclear option; generally client code shouldn't deal with protos. // However, this is used by DistSQL for sending the transaction over the wire // when it creates flows. SerializeTxn() *roachpb.Transaction }
TxnSender is the interface used to call into a CockroachDB instance when sending transactional requests. In addition to the usual Sender interface, TxnSender facilitates marshaling of transaction metadata between the "root" client.Txn and "leaf" instances.
type TxnSenderFactory interface { // TransactionalSender returns a sender to be used for transactional requests. // typ specifies whether the sender is the root or one of potentially many // child "leaf" nodes in a tree of transaction objects, as is created during a // DistSQL flow. // coordMeta is the TxnCoordMeta which contains the transaction whose requests // this sender will carry. TransactionalSender( typ TxnType, coordMeta roachpb.TxnCoordMeta, pri roachpb.UserPriority, ) TxnSender // NonTransactionalSender returns a sender to be used for non-transactional // requests. Generally this is a sender that TransactionalSender() wraps. NonTransactionalSender() Sender }
TxnSenderFactory is the interface used to create new instances of TxnSender.
TxnStatusOpt represents options for TxnSender.GetMeta().
const ( // AnyTxnStatus means GetMeta() will return the info without checking the // txn's status. AnyTxnStatus TxnStatusOpt = iota // OnlyPending means GetMeta() will return an error if the transaction is not // in the pending state. // This is used when sending the txn from root to leaves so that we don't // create leaves that start up in an aborted state - which is not allowed. OnlyPending )
TxnType specifies whether a transaction is the root (parent) transaction, or a leaf (child) in a tree of client.Txns, as is used in a DistSQL flow.
const ( // RootTxn specifies this sender is the root transaction, and is // responsible for aggregating all transactional state (see // TxnCoordMeta) and finalizing the transaction. The root txn is // responsible for heartbeating the transaction record. RootTxn TxnType // LeafTxn specifies this sender is for one of potentially many // distributed client transactions. The state from this transaction // must be propagated back to the root transaction and used to // augment its state before the transaction can be finalized. Leaf // transactions do not heartbeat the transaction record. // // Note: As leaves don't perform heartbeats, the transaction might be cleaned // up while this leaf is executing an operation. We rely on the cleanup // process poisoning the AbortSpans for all intents so that reads performed // through a leaf txn don't miss writes previously performed by the // transaction (at least not until the expiration of the GC period / abort // span entry timeout). LeafTxn )
Path | Synopsis |
---|---|
requestbatcher | Package requestbatcher is a library to enable easy batching of roachpb requests. |
Package client imports 25 packages (graph) and is imported by 437 packages. Updated 2019-12-07. Refresh now. Tools for package owners.