cockroachdb/cockroach
KV client
pkg/kv/ is the transactional key-value API exposed inside the CockroachDB binary. SQL, jobs, and internal subsystems all interact with the cluster through it. Below the API, a chain of "interceptors" produces network requests that the DistSender shards across the ranges that hold the keys.
Purpose
kv.DB, kv.Txn, and kv.Batch are the primary types. They model a single, monolithic, sorted KV map that supports Get, Put, Scan, Delete, DeleteRange, conditional puts, increments, and a few batch-only operations. Transactions are open-ended: you call db.Txn(ctx, func(txn *kv.Txn) error { ... }) and the function may be retried automatically on retryable errors.
Directory layout
pkg/kv/
├── doc.go // README-style API overview
├── db.go // kv.DB
├── txn.go // kv.Txn (~75 KB)
├── batch.go // kv.Batch
├── sender.go // generic sender abstraction
├── range_lookup.go // resolve key → range descriptor
├── kvclient/ // outbound side: DistSender, range cache, leaseholders
│ ├── kvcoord/ // TxnCoordSender + interceptors
│ ├── rangecache/ // cached range descriptors
│ ├── kvtenant/ // tenant connectors
│ ├── rangefeed/ // rangefeed client
│ └── …
├── kvpb/ // wire-level types (BatchRequest, BatchResponse, errors)
├── kvprober/ // synthetic KV probing
├── kvnemesis/ // randomized invariant testing
├── bulk/ // SST-based bulk ingestion
└── kvserver/ // server side — see systems/kvserverKey abstractions
| Type | File | Description |
|---|---|---|
DB |
pkg/kv/db.go |
Top-level KV client wrapping a Sender |
Txn |
pkg/kv/txn.go |
A transaction with refresh, savepoints, anchor key |
Batch |
pkg/kv/batch.go |
A list of Requests sent in a single round trip |
Sender |
pkg/kv/sender.go |
Anything that can dispatch a BatchRequest |
TxnCoordSender |
pkg/kv/kvclient/kvcoord/txn_coord_sender.go |
Per-txn coordinator; owns interceptor stack |
DistSender |
pkg/kv/kvclient/kvcoord/dist_sender.go |
Range-aware request dispatcher |
RangeCache |
pkg/kv/kvclient/rangecache/range_cache.go |
Cached RangeDescriptor lookups |
RangeFeed |
pkg/kv/kvclient/rangefeed/ |
Streaming change feed of a key span |
BatchRequest |
pkg/kv/kvpb/api.proto |
Wire request type |
Error |
pkg/kv/kvpb/errors.proto |
Wire-encodable error type |
TxnCoordSender interceptor stack
A kv.Txn does not send requests directly. Instead it goes through a stack of interceptors registered in TxnCoordSender:
graph LR Txn["kv.Txn"] --> CoordSender["TxnCoordSender"] CoordSender --> Heartbeater["txnHeartbeater"] Heartbeater --> Seq["txnSeqNumAllocator"] Seq --> Pipeliner["txnPipeliner"] Pipeliner --> Span["txnSpanRefresher"] Span --> Commit["txnCommitter"] Commit --> Metrics["txnMetricRecorder"] Metrics --> DistSender["DistSender"]
What each does:
- txnHeartbeater — periodically heartbeats the transaction record so it isn't reaped.
- txnSeqNumAllocator — assigns sequence numbers used for read-your-writes and savepoint rollbacks.
- txnPipeliner — pipelines writes (issues them async, tracking in-flight writes for refresh purposes).
- txnSpanRefresher — proves a transaction can advance its read timestamp without actually re-reading its read set.
- txnCommitter — implements the parallel-commit protocol (1-RPC commit when conditions allow).
- txnMetricRecorder — records timing/size metrics for observability.
DistSender
DistSender.Send (dist_sender.go) takes a BatchRequest whose requests may target many ranges. It:
- Looks up the leaseholder for each range using
RangeCache. - Splits the batch by range, preserving order where required.
- Issues RPCs to leaseholders (or to followers for follower reads).
- Re-collects responses, handling
RangeNotFoundError,NotLeaseHolderError, andRangeKeyMismatchErrorby refreshing caches and retrying.
For follower reads, pkg/kv/kvclient/kvcoord/replica_oracle.go and the pkg/kv/followerreads/ package decide which replica to ask. Any error returned to the client passes through kvpb.Error so it carries enough metadata to retry.
Range lookup
pkg/kv/range_lookup.go implements the meta-range lookup used to find the range owning a given key. The result is cached in RangeCache (pkg/kv/kvclient/rangecache/); cache invalidation is driven by errors observed during a request.
Bulk path
pkg/kv/bulk/ builds large SSTs from a stream of writes and bulk-ingests them via the AddSSTable request. This path is used by IMPORT, RESTORE, schema-change backfills, and physical-replication ingestion.
Rangefeed client
pkg/kv/kvclient/rangefeed/ consumes the server-side rangefeed (see systems/kvserver) and presents a clean Go API: RangeFeedFactory.RangeFeed(span, startTime, onValue, onDeleteRange) returns a *RangeFeed that the caller stops with Close. Used by changefeeds, span-config reconciliation, protected-timestamp reconciliation, and SQL stats persistence.
kvnemesis
pkg/kv/kvnemesis/ is a randomized invariant-testing tool: it issues random batches of operations, intentionally injects errors, and verifies that the resulting cluster history is serializable. It has caught many subtle KV bugs.
kvprober
pkg/kv/kvprober/ continuously sends synthetic KV operations and surfaces metrics — used in CI and production to catch availability regressions.
Tenants
For multi-tenant deployments, the SQL pod uses pkg/kv/kvclient/kvtenant/ instead of talking to local stores. The tenant connector authenticates the SQL pod's tenant ID and proxies requests through host-level RPCs.
Entry points for modification
- New KV operation: define the request and response in
pkg/kv/kvpb/api.proto, add the eval logic inpkg/kv/kvserver/batcheval/, register it on theSenderchain. - New transaction interceptor: implement
lockedSender/txnInterceptorinpkg/kv/kvclient/kvcoord/. - Tweak DistSender retry logic:
dist_sender.goandreplica_oracle.go. - Tracing hooks for KV: most files under
kvclient/kvcoord/already attach trace events;pkg/util/tracingis the toolkit.
Related pages
- KV server — the receiving side of
BatchRequest. - Storage / MVCC — how KV requests are evaluated against the engine.
- SQL — the main consumer of
kv.Txn. - Jobs — uses the internal executor /
kv.DBfor state.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.