storage

package
v0.0.0-...-8273b29 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 29, 2015 License: Apache-2.0 Imports: 34 Imported by: 0

Documentation

Overview

Package storage provides access to the Store and Range abstractions. Each Cockroach node handles one or more stores, each of which multiplexes to one or more ranges, identified by [start, end) keys. Ranges are contiguous regions of the keyspace. Each range implements an instance of the Raft consensus algorithm to synchronize participating range replicas.

Each store is represented by a single engine.Engine instance. The ranges hosted by a store all have access to the same engine, but write to only a range-limited keyspace within it. Ranges access the underlying engine via the MVCC interface, which provides historical versioned values.

Package storage is a generated protocol buffer package.

It is generated from these files:
	cockroach/storage/status.proto

It has these top-level messages:
	StoreStatus
Example (Rebalancing)
// Model a set of stores in a cluster,
// randomly adding / removing stores and adding bytes.
g := gossip.New(nil, 0, nil)
alloc := newAllocator(g)
alloc.randGen = rand.New(rand.NewSource(0))
alloc.deterministic = true

var wg sync.WaitGroup
g.RegisterCallback(gossip.MakePrefixPattern(gossip.KeyStorePrefix), func(_ string, _ []byte) { wg.Done() })

const generations = 100
const nodes = 20

// Initialize testStores.
var testStores [nodes]testStore
for i := 0; i < len(testStores); i++ {
	testStores[i].StoreID = proto.StoreID(i)
	testStores[i].Node = proto.NodeDescriptor{NodeID: proto.NodeID(i)}
	testStores[i].Capacity = proto.StoreCapacity{Capacity: 1 << 30, Available: 1 << 30}
}
// Initialize the cluster with a single range.
testStores[0].Add(alloc.randGen.Int63n(1 << 20))

for i := 0; i < generations; i++ {
	// First loop through test stores and add data.
	wg.Add(len(testStores))
	for j := 0; j < len(testStores); j++ {
		// Add a pretend range to the testStore if there's already one.
		if testStores[j].Capacity.RangeCount > 0 {
			testStores[j].Add(alloc.randGen.Int63n(1 << 20))
		}
		key := gossip.MakeStoreKey(proto.StoreID(j))
		if err := g.AddInfoProto(key, &testStores[j].StoreDescriptor, 0); err != nil {
			panic(err)
		}
	}
	wg.Wait()

	// Next loop through test stores and maybe rebalance.
	for j := 0; j < len(testStores); j++ {
		ts := &testStores[j]
		if alloc.ShouldRebalance(&testStores[j].StoreDescriptor) {
			target := alloc.RebalanceTarget(proto.Attributes{}, []proto.Replica{{NodeID: ts.Node.NodeID, StoreID: ts.StoreID}})
			if target != nil {
				testStores[j].Rebalance(&testStores[int(target.StoreID)], alloc.randGen.Int63n(1<<20))
			}
		}
	}

	// Output store capacities as hexidecimal 2-character values.
	if i%(generations/50) == 0 {
		var maxBytes int64
		for j := 0; j < len(testStores); j++ {
			bytes := testStores[j].Capacity.Capacity - testStores[j].Capacity.Available
			if bytes > maxBytes {
				maxBytes = bytes
			}
		}
		if maxBytes > 0 {
			for j := 0; j < len(testStores); j++ {
				endStr := " "
				if j == len(testStores)-1 {
					endStr = ""
				}
				bytes := testStores[j].Capacity.Capacity - testStores[j].Capacity.Available
				fmt.Printf("%03d%s", (999*bytes)/maxBytes, endStr)
			}
			fmt.Printf("\n")
		}
	}
}

var totBytes int64
var totRanges int32
for i := 0; i < len(testStores); i++ {
	totBytes += testStores[i].Capacity.Capacity - testStores[i].Capacity.Available
	totRanges += testStores[i].Capacity.RangeCount
}
fmt.Printf("Total bytes=%d, ranges=%d\n", totBytes, totRanges)
Output:

999 000 000 000 000 000 000 739 000 000 000 000 000 000 000 000 000 000 000 000
999 107 000 000 204 000 000 375 000 000 000 000 000 000 000 000 000 000 536 000
999 310 000 262 872 000 000 208 000 705 000 526 000 000 439 000 000 607 933 000
812 258 000 220 999 673 402 480 000 430 516 374 000 431 318 000 551 714 917 000
582 625 185 334 720 589 647 619 000 300 483 352 279 502 208 665 816 684 999 374
751 617 771 542 738 676 665 525 309 435 612 449 457 616 306 837 993 754 999 445
759 659 828 478 693 622 594 591 349 458 630 538 526 613 462 827 879 787 999 550
861 658 828 559 801 660 681 560 487 529 652 686 642 716 575 999 989 875 989 581
775 647 724 557 779 662 670 494 535 502 681 676 624 695 561 961 999 772 888 592
856 712 753 661 767 658 717 606 529 615 755 699 672 700 576 955 999 755 861 671
882 735 776 685 844 643 740 578 610 688 787 741 661 767 587 999 955 809 803 731
958 716 789 719 861 689 821 608 634 724 800 782 694 799 619 994 999 851 812 818
949 726 788 664 873 633 749 599 680 714 790 728 663 842 628 999 978 816 823 791
923 698 792 712 816 605 774 651 661 728 802 718 670 819 714 999 966 801 829 791
962 779 847 737 900 675 811 691 745 778 835 812 680 894 790 999 989 872 923 799
967 812 826 772 891 685 828 683 761 808 864 820 643 873 783 969 999 873 910 781
923 813 837 739 867 672 792 664 773 772 879 803 610 845 740 957 999 867 912 732
952 803 866 759 881 655 765 668 803 772 929 762 601 844 751 973 999 892 864 731
970 777 867 800 859 639 774 662 787 760 906 751 595 854 732 989 999 853 859 762
943 776 872 787 861 686 780 663 789 793 926 784 612 832 733 999 968 868 827 767
914 801 912 802 878 704 800 685 818 808 939 759 627 844 717 999 976 872 828 757
935 806 911 797 887 710 798 711 826 824 938 775 614 870 716 999 986 886 803 767
991 851 898 856 872 795 828 782 826 852 963 797 710 868 775 994 999 923 896 794
999 924 866 877 884 883 886 836 846 869 953 851 762 887 858 985 949 900 917 836
999 910 887 878 897 890 906 868 906 903 983 947 801 895 913 976 924 890 904 898
955 884 888 916 886 879 901 872 898 883 999 874 829 888 892 937 918 889 891 862
974 952 957 990 950 976 945 946 980 961 999 975 942 926 957 994 965 946 960 960
949 929 952 999 929 961 943 946 993 918 984 961 952 919 953 950 952 941 949 934
907 999 916 935 903 903 909 907 960 939 973 912 901 885 916 910 941 911 906 913
939 999 948 948 945 962 951 954 952 964 996 942 975 962 962 956 971 969 975 969
940 974 964 947 971 975 949 954 953 970 992 971 981 973 948 962 999 969 978 975
950 971 953 938 962 967 930 964 953 978 999 945 974 972 951 950 998 951 949 962
934 946 943 936 942 949 929 956 928 970 989 944 945 923 987 927 999 942 931 944
939 957 942 958 951 970 937 946 930 950 940 959 963 937 973 943 999 931 949 940
933 935 945 929 933 960 937 935 919 918 930 931 950 924 969 935 999 943 949 926
959 941 948 952 948 957 936 937 943 930 955 962 953 949 980 948 999 934 980 942
950 973 954 962 949 964 935 949 925 936 951 962 979 962 999 942 990 948 969 959
937 993 958 949 960 960 942 954 969 950 951 952 974 970 999 927 979 964 975 944
981 986 971 968 964 984 954 959 985 979 966 963 994 963 999 970 991 971 988 965
967 997 961 957 959 985 956 940 955 955 957 955 970 952 979 964 999 951 960 968
937 969 931 950 945 954 932 925 954 946 944 926 955 938 957 949 999 934 947 938
958 967 954 955 971 973 946 934 979 947 944 958 954 954 960 948 999 936 960 951
950 948 940 958 937 955 928 927 953 923 935 939 934 921 934 934 999 922 940 938
960 960 929 962 955 955 926 935 957 928 939 941 938 926 941 924 999 923 957 942
979 958 947 987 980 972 945 943 984 939 951 943 944 946 942 942 999 928 970 943
981 941 931 961 969 962 927 935 985 925 964 945 946 939 946 938 999 933 964 928
980 944 929 970 973 955 942 937 977 920 955 929 937 946 935 933 999 947 956 926
980 948 926 981 938 939 936 936 963 949 965 935 943 946 933 933 999 947 955 943
968 959 945 941 929 926 924 941 970 951 959 941 924 952 931 943 999 941 951 950
961 946 930 923 933 932 953 937 954 940 964 944 931 952 939 935 999 936 945 948
Total bytes=996294324, ranges=1897

Index

Examples

Constants

View Source
const (
	// DefaultHeartbeatInterval is how often heartbeats are sent from the
	// transaction coordinator to a live transaction. These keep it from
	// being preempted by other transactions writing the same keys. If a
	// transaction fails to be heartbeat within 2x the heartbeat interval,
	// it may be aborted by conflicting txns.
	DefaultHeartbeatInterval = 5 * time.Second
)
View Source
const (

	// DefaultLeaderLeaseDuration is the default duration of the leader lease.
	DefaultLeaderLeaseDuration = time.Second
)

raftInitialLogIndex is the starting point for the raft log. We bootstrap the raft membership by synthesizing a snapshot as if there were some discarded prefix to the log, so we must begin the log at an arbitrary index greater than 1.

View Source
const (
	// GCResponseCacheExpiration is the expiration duration for response
	// cache entries.
	GCResponseCacheExpiration = 1 * time.Hour
)
View Source
const (
	// MinTSCacheWindow specifies the minimum duration to hold entries in
	// the cache before allowing eviction. After this window expires,
	// transactions writing to this node with timestamps lagging by more
	// than minCacheWindow will necessarily have to advance their commit
	// timestamp.
	MinTSCacheWindow = 10 * time.Second
)
View Source
const (

	// RangeGCQueueInactivityThreshold is the inactivity duration after which
	// a range will be considered for garbage collection. Exported for testing.
	RangeGCQueueInactivityThreshold = 10 * 24 * time.Hour // 10 days
)

Variables

View Source
var (
	ErrInvalidLengthStatus = fmt.Errorf("proto: negative length found during unmarshaling")
)
View Source
var (

	// TestStoreContext has some fields initialized with values relevant
	// in tests.
	TestStoreContext = StoreContext{
		RaftTickInterval:           100 * time.Millisecond,
		RaftHeartbeatIntervalTicks: 1,
		RaftElectionTimeoutTicks:   2,
		ScanInterval:               10 * time.Minute,
	}
)
View Source
var TestingCommandFilter func(proto.Request) error

TestingCommandFilter may be set in tests to intercept the handling of commands and artificially generate errors. Return nil to continue with regular processing or non-nil to terminate processing with the returned error. Note that in a multi-replica test this filter will be run once for each replica and must produce consistent results each time. Should only be used in tests in the storage and storage_test packages.

Functions

func DeleteRange

func DeleteRange(txn *client.Txn, b *client.Batch, key proto.Key) error

DeleteRange removes a range from the RangeTree. This should only be called from operations that remove ranges, such as AdminMerge.

func InsertRange

func InsertRange(txn *client.Txn, b *client.Batch, key proto.Key) error

InsertRange adds a new range to the RangeTree. This should only be called from operations that create new ranges, such as AdminSplit.

func ProcessStoreEvent

func ProcessStoreEvent(l StoreEventListener, event interface{})

ProcessStoreEvent dispatches an event on the StoreEventListener.

func SetupRangeTree

func SetupRangeTree(batch engine.Engine, ms *engine.MVCCStats, timestamp proto.Timestamp, startKey proto.Key) error

SetupRangeTree creates a new RangeTree. This should only be called as part of store.BootstrapRange.

Types

type BeginScanRangesEvent

type BeginScanRangesEvent struct {
	StoreID proto.StoreID
}

BeginScanRangesEvent occurs when the store is about to scan over all ranges. During such a scan, each existing range will be published to the feed as a RegisterRangeEvent with the Scan flag set. This is used because downstream consumers may be tracking statistics via the Deltas in UpdateRangeEvent; this event informs subscribers to clear currently cached values.

type CommandQueue

type CommandQueue struct {
	// contains filtered or unexported fields
}

A CommandQueue maintains an interval tree of keys or key ranges for executing commands. New commands affecting keys or key ranges must wait on already-executing commands which overlap their key range.

Before executing, a command invokes GetWait() to initialize a WaitGroup with the number of overlapping commands which are already running. The wait group is waited on by the caller for confirmation that all overlapping, pending commands have completed and the pending command can proceed.

After waiting, a command is added to the queue's already-executing set via Add(). Add accepts a parameter indicating whether the command is read-only. Read-only commands don't need to wait on other read-only commands, so the wait group returned via GetWait() doesn't include read-only on read-only overlapping commands as an optimization.

Once commands complete, Remove() is invoked to remove the executing command and decrement the counts on any pending WaitGroups, possibly signaling waiting commands who were gated by the executing command's affected key(s).

CommandQueue is not thread safe.

func NewCommandQueue

func NewCommandQueue() *CommandQueue

NewCommandQueue returns a new command queue.

func (*CommandQueue) Add

func (cq *CommandQueue) Add(start, end proto.Key, readOnly bool) interface{}

Add adds a command to the queue which affects the specified key range. If end is empty, it is set to start.Next(), meaning the command affects a single key. The returned interface is the key for the command queue and must be re-supplied on subsequent invocation of Remove().

Add should be invoked after waiting on already-executing, overlapping commands via the WaitGroup initialized through GetWait().

func (*CommandQueue) Clear

func (cq *CommandQueue) Clear()

Clear removes all executing commands, signaling any waiting commands.

func (*CommandQueue) GetWait

func (cq *CommandQueue) GetWait(start, end proto.Key, readOnly bool, wg *sync.WaitGroup)

GetWait initializes the supplied wait group with the number of executing commands which overlap the specified key range. If end is empty, end is set to start.Next(), meaning the command affects a single key. The caller should call wg.Wait() to wait for confirmation that all gating commands have completed or failed. readOnly is true if the requester is a read-only command; false for read-write.

func (*CommandQueue) Remove

func (cq *CommandQueue) Remove(key interface{})

Remove is invoked to signal that the command associated with the specified key has completed and should be removed. Any pending commands waiting on this command will be signaled if this is the only command upon which they are still waiting.

Remove is invoked after a mutating command has been committed to the Raft log and applied to the underlying state machine. Similarly, Remove is invoked after a read-only command has been executed against the underlying state machine.

type EndScanRangesEvent

type EndScanRangesEvent struct {
	StoreID proto.StoreID
}

EndScanRangesEvent occurs when the store has finished scanning all ranges. Every BeginScanRangeEvent will eventually be followed by an EndScanRangeEvent.

type MergeRangeEvent

type MergeRangeEvent struct {
	StoreID proto.StoreID
	Merged  UpdateRangeEvent
	Removed RemoveRangeEvent
}

MergeRangeEvent occurs whenever a range is merged into another. This Event contains two component events: an UpdateRangeEvent for the range which subsumed the other, and a RemoveRangeEvent for the range that was subsumed.

type NotBootstrappedError

type NotBootstrappedError struct{}

A NotBootstrappedError indicates that an engine has not yet been bootstrapped due to a store identifier not being present.

func (*NotBootstrappedError) Error

func (e *NotBootstrappedError) Error() string

Error formats error.

type RegisterRangeEvent

type RegisterRangeEvent struct {
	StoreID proto.StoreID
	Desc    *proto.RangeDescriptor
	Stats   engine.MVCCStats
	Scan    bool
}

RegisterRangeEvent occurs in two scenarios. Firstly, while a store broadcasts its list of ranges to initialize one or more new accumulators (with Scan set to true), or secondly, when a new range is initialized on the store (for example through replication), with Scan set to false. This event includes the Range's RangeDescriptor and current MVCCStats.

type RemoveRangeEvent

type RemoveRangeEvent struct {
	StoreID proto.StoreID
	Desc    *proto.RangeDescriptor
	Stats   engine.MVCCStats
}

RemoveRangeEvent occurs whenever a Range is removed from a store. This structure includes the Range's RangeDescriptor and the Range's previous MVCCStats before it was removed.

type Replica

type Replica struct {
	sync.RWMutex // Protects the following fields:
	// contains filtered or unexported fields
}

A Replica is a contiguous keyspace with writes managed via an instance of the Raft consensus algorithm. Many ranges may exist in a store and they are unlikely to be contiguous. Ranges are independent units and are responsible for maintaining their own integrity by replacing failed replicas, splitting and merging as appropriate.

func NewReplica

func NewReplica(desc *proto.RangeDescriptor, rm rangeManager) (*Replica, error)

NewReplica initializes the replica using the given metadata.

func (*Replica) AddCmd

func (r *Replica) AddCmd(ctx context.Context, args proto.Request) (proto.Response, error)

AddCmd adds a command for execution on this range. The command's affected keys are verified to be contained within the range and the range's leadership is confirmed. The command is then dispatched either along the read-only execution path or the read-write Raft command queue.

func (*Replica) AdminMerge

AdminMerge extends the range to subsume the range that comes next in the key space. The range being subsumed is provided in args.SubsumedRange. The EndKey of the subsuming range must equal the start key of the range being subsumed. The merge is performed inside of a distributed transaction which writes the updated range descriptor for the subsuming range and deletes the range descriptor for the subsumed one. It also updates the range addressing metadata. The handover of responsibility for the reassigned key range is carried out seamlessly through a merge trigger carried out as part of the commit of that transaction. A merge requires that the two ranges are collocate on the same set of replicas.

The supplied RangeDescriptor is used as a form of optimistic lock. See the comment of "AdminSplit" for more information on this pattern.

func (*Replica) AdminSplit

AdminSplit divides the range into into two ranges, using either args.SplitKey (if provided) or an internally computed key that aims to roughly equipartition the range by size. The split is done inside of a distributed txn which writes updated and new range descriptors, and updates the range addressing metadata. The handover of responsibility for the reassigned key range is carried out seamlessly through a split trigger carried out as part of the commit of that transaction.

The supplied RangeDescriptor is used as a form of optimistic lock. An operation which might split a range should obtain a copy of the range's current descriptor before making the decision to split. If the decision is affirmative the descriptor is passed to AdminSplit, which performs a Conditional Put on the RangeDescriptor to ensure that no other operation has modified the range in the time the decision was being made.

func (*Replica) Append

func (r *Replica) Append(entries []raftpb.Entry) error

Append implements the multiraft.WriteableGroupStorage interface.

func (*Replica) ApplySnapshot

func (r *Replica) ApplySnapshot(snap raftpb.Snapshot) error

ApplySnapshot implements the multiraft.WriteableGroupStorage interface.

func (*Replica) ChangeReplicas

func (r *Replica) ChangeReplicas(changeType proto.ReplicaChangeType, replica proto.Replica, desc *proto.RangeDescriptor) error

ChangeReplicas adds or removes a replica of a range. The change is performed in a distributed transaction and takes effect when that transaction is committed. When removing a replica, only the NodeID and StoreID fields of the Replica are used.

The supplied RangeDescriptor is used as a form of optimistic lock. See the comment of "AdminSplit" for more information on this pattern.

func (*Replica) ConditionalPut

ConditionalPut sets the value for a specified key only if the expected value matches. If not, the return value contains the actual value.

func (*Replica) ContainsKey

func (r *Replica) ContainsKey(key proto.Key) bool

ContainsKey returns whether this range contains the specified key.

func (*Replica) ContainsKeyRange

func (r *Replica) ContainsKeyRange(start, end proto.Key) bool

ContainsKeyRange returns whether this range contains the specified key range from start to end.

func (*Replica) Delete

Delete deletes the key and value specified by key.

func (*Replica) DeleteRange

DeleteRange deletes the range of key/value pairs specified by start and end keys.

func (*Replica) Desc

func (r *Replica) Desc() *proto.RangeDescriptor

Desc atomically returns the range's descriptor.

func (*Replica) Destroy

func (r *Replica) Destroy() error

Destroy cleans up all data associated with this range.

func (*Replica) EndTransaction

EndTransaction either commits or aborts (rolls back) an extant transaction according to the args.Commit parameter.

func (*Replica) Entries

func (r *Replica) Entries(lo, hi, maxBytes uint64) ([]raftpb.Entry, error)

Entries implements the raft.Storage interface. Note that maxBytes is advisory and this method will always return at least one entry even if it exceeds maxBytes. Passing maxBytes equal to zero disables size checking. TODO(bdarnell): consider caching for recent entries, if rocksdb's builtin caching is insufficient.

func (*Replica) FirstIndex

func (r *Replica) FirstIndex() (uint64, error)

FirstIndex implements the raft.Storage interface.

func (*Replica) GC

GC iterates through the list of keys to garbage collect specified in the arguments. MVCCGarbageCollect is invoked on each listed key along with the expiration timestamp. The GC metadata specified in the args is persisted after GC.

func (*Replica) Get

func (r *Replica) Get(batch engine.Engine, args proto.GetRequest) (proto.GetResponse, []proto.Intent, error)

Get returns the value for a specified key.

func (*Replica) GetGCMetadata

func (r *Replica) GetGCMetadata() (*proto.GCMetadata, error)

GetGCMetadata reads the latest GC metadata for this range.

func (*Replica) GetLastVerificationTimestamp

func (r *Replica) GetLastVerificationTimestamp() (proto.Timestamp, error)

GetLastVerificationTimestamp reads the timestamp at which the range's data was last verified.

func (*Replica) GetMVCCStats

func (r *Replica) GetMVCCStats() engine.MVCCStats

GetMVCCStats returns a copy of the MVCC stats object for this range.

func (*Replica) GetMaxBytes

func (r *Replica) GetMaxBytes() int64

GetMaxBytes atomically gets the range maximum byte limit.

func (*Replica) GetReplica

func (r *Replica) GetReplica() *proto.Replica

GetReplica returns the replica for this range from the range descriptor. Returns nil if the replica is not found.

func (*Replica) HeartbeatTxn

HeartbeatTxn updates the transaction status and heartbeat timestamp after receiving transaction heartbeat messages from coordinator. Returns the updated transaction.

func (*Replica) Increment

Increment increments the value (interpreted as varint64 encoded) and returns the newly incremented value (encoded as varint64). If no value exists for the key, zero is incremented.

func (*Replica) InitialState

func (r *Replica) InitialState() (raftpb.HardState, raftpb.ConfState, error)

InitialState implements the raft.Storage interface.

func (*Replica) IsFirstRange

func (r *Replica) IsFirstRange() bool

IsFirstRange returns true if this is the first range.

func (*Replica) LastIndex

func (r *Replica) LastIndex() (uint64, error)

LastIndex implements the raft.Storage interface.

func (*Replica) LeaderLease

LeaderLease sets the leader lease for this range. The command fails only if the desired start timestamp collides with a previous lease. Otherwise, the start timestamp is wound back to right after the expiration of the previous lease (or zero). If this range replica is already the lease holder, the expiration will be extended or shortened as indicated. For a new lease, all duties required of the range leader are commenced, including clearing the command queue and timestamp cache.

func (*Replica) Less

func (r *Replica) Less(i btree.Item) bool

Less returns true if the range's end key is less than the given item's key.

func (*Replica) Merge

Merge is used to merge a value into an existing key. Merge is an efficient accumulation operation which is exposed by RocksDB, used by Cockroach for the efficient accumulation of certain values. Due to the difficulty of making these operations transactional, merges are not currently exposed directly to clients. Merged values are explicitly not MVCC data.

func (*Replica) PushTxn

PushTxn resolves conflicts between concurrent txns (or between a non-transactional reader or writer and a txn) in several ways depending on the statuses and priorities of the conflicting transactions. The PushTxn operation is invoked by a "pusher" (the writer trying to abort a conflicting txn or the reader trying to push a conflicting txn's commit timestamp forward), who attempts to resolve a conflict with a "pushee" (args.PushTxn -- the pushee txn whose intent(s) caused the conflict).

Txn already committed/aborted: If pushee txn is committed or aborted return success.

Txn Timeout: If pushee txn entry isn't present or its LastHeartbeat timestamp isn't set, use PushTxn.Timestamp as LastHeartbeat. If current time - LastHeartbeat > 2 * DefaultHeartbeatInterval, then the pushee txn should be either pushed forward, aborted, or confirmed not pending, depending on value of Request.PushType.

Old Txn Epoch: If persisted pushee txn entry has a newer Epoch than PushTxn.Epoch, return success, as older epoch may be removed.

Lower Txn Priority: If pushee txn has a lower priority than pusher, adjust pushee's persisted txn depending on value of args.PushType. If args.PushType is ABORT_TXN, set txn.Status to ABORTED, and priority to one less than the pusher's priority and return success. If args.PushType is PUSH_TIMESTAMP, set txn.Timestamp to pusher's Timestamp + 1 (note that we use the pusher's Args.Timestamp, not Txn.Timestamp because the args timestamp can advance during the txn).

Higher Txn Priority: If pushee txn has a higher priority than pusher, return TransactionPushError. Transaction will be retried with priority one less than the pushee's higher priority.

func (*Replica) Put

Put sets the value for a specified key.

func (*Replica) RangeLookup

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.

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 dispatching it to RangeLookup.

Note that the Range Metadata Key sent to RangeLookup 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 originally used to generate the Range Metadata Key sent to RangeLookup.

The "Range Metadata Key" for a range is built by appending the end key of the range to the respective meta prefix.

Lookups for range metadata keys usually want to read inconsistently, but some callers need a consistent result; both are supported.

This method has an important optimization in the inconsistent case: 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 the requesting nodes can aggressively cache RangeDescriptors which are likely to be desired by their current workload. The Reverse flag specifies whether descriptors are prefetched in descending or ascending order.

func (*Replica) ResolveIntent

ResolveIntent resolves a write intent from the specified key according to the status of the transaction which created it.

func (*Replica) ResolveIntentRange

ResolveIntentRange resolves write intents in the specified key range according to the status of the transaction which created it.

func (*Replica) ReverseScan

ReverseScan scans the key range specified by start key through end key in descending order up to some maximum number of results.

func (*Replica) Scan

Scan scans the key range specified by start key through end key in ascending order up to some maximum number of results.

func (*Replica) SetHardState

func (r *Replica) SetHardState(st raftpb.HardState) error

SetHardState implements the multiraft.WriteableGroupStorage interface.

func (*Replica) SetLastVerificationTimestamp

func (r *Replica) SetLastVerificationTimestamp(timestamp proto.Timestamp) error

SetLastVerificationTimestamp writes the timestamp at which the range's data was last verified.

func (*Replica) SetMaxBytes

func (r *Replica) SetMaxBytes(maxBytes int64)

SetMaxBytes atomically sets the maximum byte limit before split. This value is cached by the range for efficiency.

func (*Replica) Snapshot

func (r *Replica) Snapshot() (raftpb.Snapshot, error)

Snapshot implements the raft.Storage interface.

func (*Replica) String

func (r *Replica) String() string

String returns a string representation of the range.

func (*Replica) Term

func (r *Replica) Term(i uint64) (uint64, error)

Term implements the raft.Storage interface.

func (*Replica) TruncateLog

TruncateLog discards a prefix of the raft log.

func (*Replica) WaitForLeaderLease

func (r *Replica) WaitForLeaderLease(t util.Tester)

WaitForLeaderLease is used from unittests to wait until this range has the leader lease.

type ReplicationStatusEvent

type ReplicationStatusEvent struct {
	StoreID proto.StoreID

	// Per-range availability information, which is currently computed by
	// periodically polling the ranges of each store.
	// TODO(mrtracy): See if this information could be computed incrementally
	// from other events.
	LeaderRangeCount     int32
	ReplicatedRangeCount int32
	AvailableRangeCount  int32
}

ReplicationStatusEvent contains statistics on the replication status of the ranges in the store.

Because these statistics cannot currently be computed from other events, this event should be periodically broadcast by the store independently of other operations.

type ResponseCache

type ResponseCache struct {
	// contains filtered or unexported fields
}

A ResponseCache provides idempotence for request retries. Each request to a range specifies a ClientCmdID in the request header which uniquely identifies a client command. After commands have been replicated via Raft, they are executed against the state machine and the results are stored in the ResponseCache.

The ResponseCache stores responses in the underlying engine, using keys derived from the Range ID and the ClientCmdID.

A ResponseCache is not thread safe. Access to it is serialized through Raft.

func NewResponseCache

func NewResponseCache(rangeID proto.RangeID) *ResponseCache

NewResponseCache returns a new response cache. Every range replica maintains a response cache, not just the leader. However, when a replica loses or gains leadership of the Raft consensus group, the inflight map should be cleared.

func (*ResponseCache) ClearData

func (rc *ResponseCache) ClearData(e engine.Engine) error

ClearData removes all items stored in the persistent cache. It does not alter the inflight map.

func (*ResponseCache) CopyFrom

func (rc *ResponseCache) CopyFrom(e engine.Engine, originRangeID proto.RangeID) error

CopyFrom copies all the cached results from the originRangeID response cache into this one. Note that the cache will not be locked while copying is in progress. Failures decoding individual cache entries return an error. The copy is done directly using the engine instead of interpreting values through MVCC for efficiency.

func (*ResponseCache) CopyInto

func (rc *ResponseCache) CopyInto(e engine.Engine, destRangeID proto.RangeID) error

CopyInto copies all the cached results from this response cache into the destRangeID response cache. Failures decoding individual cache entries return an error.

func (*ResponseCache) GetResponse

GetResponse looks up a response matching the specified cmdID. If the response is found, it is returned along with its associated error. If the response is not found, nil is returned for both the response and its error. In all cases, the third return value is the error returned from the engine when reading the on-disk cache.

func (*ResponseCache) PutResponse

func (rc *ResponseCache) PutResponse(e engine.Engine, cmdID proto.ClientCmdID, replyWithErr proto.ResponseWithError) error

PutResponse writes a response and an error associated with it to the cache for the specified cmdID.

type SplitRangeEvent

type SplitRangeEvent struct {
	StoreID  proto.StoreID
	Original UpdateRangeEvent
	New      RegisterRangeEvent
}

SplitRangeEvent occurs whenever a range is split in two. This Event actually contains two other events: an UpdateRangeEvent for the Range which originally existed, and a RegisterRangeEvent for the range created via the split.

type StartStoreEvent

type StartStoreEvent struct {
	StoreID   proto.StoreID
	StartedAt int64
}

StartStoreEvent occurs whenever a store is initially started.

type Store

type Store struct {
	Ident proto.StoreIdent
	// contains filtered or unexported fields
}

A Store maintains a map of ranges by start key. A Store corresponds to one physical device.

func NewStore

func NewStore(ctx StoreContext, eng engine.Engine, nodeDesc *proto.NodeDescriptor) *Store

NewStore returns a new instance of a store.

func (*Store) AddReplicaTest

func (s *Store) AddReplicaTest(rng *Replica) error

AddReplicaTest adds the replica to the store's replica map and to the sorted replicasByKey slice. To be used only by unittests.

func (*Store) AppliedIndex

func (s *Store) AppliedIndex(groupID proto.RangeID) (uint64, error)

AppliedIndex implements the multiraft.StateMachine interface.

func (*Store) Attrs

func (s *Store) Attrs() proto.Attributes

Attrs returns the attributes of the underlying store.

func (*Store) Bootstrap

func (s *Store) Bootstrap(ident proto.StoreIdent, stopper *stop.Stopper) error

Bootstrap writes a new store ident to the underlying engine. To ensure that no crufty data already exists in the engine, it scans the engine contents before writing the new store ident. The engine should be completely empty. It returns an error if called on a non-empty engine.

func (*Store) BootstrapRange

func (s *Store) BootstrapRange(initialValues []proto.KeyValue) error

BootstrapRange creates the first range in the cluster and manually writes it to the store. Default range addressing records are created for meta1 and meta2. Default configurations for zones are created. All configs are specified for the empty key prefix, meaning they apply to the entire database. The zone requires three replicas with no other specifications. It also adds the range tree and the root node, the first range, to it. The 'initialValues' are written as well after each value's checksum is initalized.

func (*Store) Capacity

func (s *Store) Capacity() (proto.StoreCapacity, error)

Capacity returns the capacity of the underlying storage engine.

func (*Store) Clock

func (s *Store) Clock() *hlc.Clock

Clock accessor.

func (*Store) ClusterID

func (s *Store) ClusterID() string

ClusterID accessor.

func (*Store) Context

func (s *Store) Context(ctx context.Context) context.Context

Context returns a base context to pass along with commands being executed, derived from the supplied context (which is allowed to be nil).

func (*Store) DB

func (s *Store) DB() *client.DB

DB accessor.

func (*Store) Descriptor

func (s *Store) Descriptor() (*proto.StoreDescriptor, error)

Descriptor returns a StoreDescriptor including current store capacity information.

func (*Store) DisableRangeGCQueue

func (s *Store) DisableRangeGCQueue(disabled bool)

DisableRangeGCQueue disables or enables the range GC queue. Exposed only for testing.

func (*Store) Engine

func (s *Store) Engine() engine.Engine

Engine accessor.

func (*Store) EventFeed

func (s *Store) EventFeed() StoreEventFeed

EventFeed accessor.

func (*Store) ExecuteCmd

func (s *Store) ExecuteCmd(ctx context.Context, args proto.Request) (proto.Response, error)

ExecuteCmd fetches a range based on the header's replica, assembles method, args & reply into a Raft Cmd struct and executes the command using the fetched range.

func (*Store) ForceRangeGCScan

func (s *Store) ForceRangeGCScan(t util.Tester)

ForceRangeGCScan iterates over all ranges and enqueues any that may need to be GC'd. Exposed only for testing.

func (*Store) ForceReplicationScan

func (s *Store) ForceReplicationScan(t util.Tester)

ForceReplicationScan iterates over all ranges and enqueues any that need to be replicated. Exposed only for testing.

func (*Store) GetReplica

func (s *Store) GetReplica(rangeID proto.RangeID) (*Replica, error)

GetReplica fetches a replica by Range ID. Returns an error if no replica is found.

func (*Store) GetStatus

func (s *Store) GetStatus() (*StoreStatus, error)

GetStatus fetches the latest store status from the stored value on the cluster. Returns nil if the scanner has not yet run. The scanner runs once every ctx.ScanInterval.

func (*Store) Gossip

func (s *Store) Gossip() *gossip.Gossip

Gossip accessor.

func (*Store) GossipStore

func (s *Store) GossipStore()

GossipStore broadcasts the store on the gossip network.

func (*Store) GroupStorage

func (s *Store) GroupStorage(groupID proto.RangeID) multiraft.WriteableGroupStorage

GroupStorage implements the multiraft.Storage interface.

func (*Store) IsStarted

func (s *Store) IsStarted() bool

IsStarted returns true if the Store has been started.

func (*Store) LookupReplica

func (s *Store) LookupReplica(start, end proto.Key) *Replica

LookupReplica looks up a replica via binary search over the "replicasByKey" btree. Returns nil if no replica is found for specified key range. Note that the specified keys are transformed using Key.Address() to ensure we lookup replicas correctly for local keys. When end is nil, a replica that contains start is looked up.

func (*Store) MergeRange

func (s *Store) MergeRange(subsumingRng *Replica, updatedEndKey proto.Key, subsumedRangeID proto.RangeID) error

MergeRange expands the subsuming range to absorb the subsumed range. This merge operation will fail if the two ranges are not collocated on the same store.

func (*Store) NewRangeDescriptor

func (s *Store) NewRangeDescriptor(start, end proto.Key, replicas []proto.Replica) (*proto.RangeDescriptor, error)

NewRangeDescriptor creates a new descriptor based on start and end keys and the supplied proto.Replicas slice. It allocates new replica IDs to fill out the supplied replicas.

func (*Store) NewSnapshot

func (s *Store) NewSnapshot() engine.Engine

NewSnapshot creates a new snapshot engine.

func (*Store) ProposeRaftCommand

func (s *Store) ProposeRaftCommand(idKey cmdIDKey, cmd proto.RaftCommand) <-chan error

ProposeRaftCommand submits a command to raft. The command is processed asynchronously and an error or nil will be written to the returned channel when it is committed or aborted (but note that committed does mean that it has been applied to the range yet).

func (*Store) PublishStatus

func (s *Store) PublishStatus() error

PublishStatus publishes periodically computed status events to the store's events feed. This method itself should be periodically called by some external mechanism.

func (*Store) RaftNodeID

func (s *Store) RaftNodeID() proto.RaftNodeID

RaftNodeID accessor.

func (*Store) RaftStatus

func (s *Store) RaftStatus(rangeID proto.RangeID) *raft.Status

RaftStatus returns the current raft status of the given range.

func (*Store) RemoveReplica

func (s *Store) RemoveReplica(rng *Replica) error

RemoveReplica removes the replica from the store's replica map and from the sorted replicasByKey btree.

func (*Store) ReplicaCount

func (s *Store) ReplicaCount() int

ReplicaCount returns the number of replicas contained by this store.

func (*Store) SetRangeRetryOptions

func (s *Store) SetRangeRetryOptions(ro retry.Options)

SetRangeRetryOptions sets the retry options used for this store. For unittests only.

func (*Store) SplitRange

func (s *Store) SplitRange(origRng, newRng *Replica) error

SplitRange shortens the original range to accommodate the new range. The new range is added to the ranges map and the rangesByKey btree.

func (*Store) Start

func (s *Store) Start(stopper *stop.Stopper) error

Start the engine, set the GC and read the StoreIdent.

func (*Store) StartedAt

func (s *Store) StartedAt() int64

StartedAt returns the timestamp at which the store was most recently started.

func (*Store) Stopper

func (s *Store) Stopper() *stop.Stopper

Stopper accessor.

func (*Store) StoreID

func (s *Store) StoreID() proto.StoreID

StoreID accessor.

func (*Store) String

func (s *Store) String() string

String formats a store for debug output.

func (*Store) Tracer

func (s *Store) Tracer() *tracer.Tracer

Tracer accessor.

func (*Store) WaitForInit

func (s *Store) WaitForInit()

WaitForInit waits for any asynchronous processes begun in Start() to complete their initialization. In particular, this includes gossiping. In some cases this may block until the range GC queue has completed its scan. Only for testing.

type StoreContext

type StoreContext struct {
	Clock     *hlc.Clock
	DB        *client.DB
	Gossip    *gossip.Gossip
	Transport multiraft.Transport

	// RangeRetryOptions are the retry options when retryable errors are
	// encountered sending commands to ranges.
	RangeRetryOptions retry.Options

	// RaftTickInterval is the resolution of the Raft timer; other raft timeouts
	// are defined in terms of multiples of this value.
	RaftTickInterval time.Duration

	// RaftHeartbeatIntervalTicks is the number of ticks that pass between heartbeats.
	RaftHeartbeatIntervalTicks int

	// RaftElectionTimeoutTicks is the number of ticks that must pass before a follower
	// considers a leader to have failed and calls a new election. Should be significantly
	// higher than RaftHeartbeatIntervalTicks. The raft paper recommends a value of 150ms
	// for local networks.
	RaftElectionTimeoutTicks int

	// ScanInterval is the default value for the scan interval
	ScanInterval time.Duration

	// ScanMaxIdleTime is the maximum time the scanner will be idle between ranges.
	// If enabled (> 0), the scanner may complete in less than ScanInterval for small
	// stores.
	ScanMaxIdleTime time.Duration

	// EventFeed is a feed to which this store will publish events.
	EventFeed *util.Feed

	// Tracer is a request tracer.
	Tracer *tracer.Tracer
}

A StoreContext encompasses the auxiliary objects and configuration required to create a store. All fields holding a pointer or an interface are required to create a store; the rest will have sane defaults set if omitted.

func (*StoreContext) Valid

func (sc *StoreContext) Valid() bool

Valid returns true if the StoreContext is populated correctly. We don't check for Gossip and DB since some of our tests pass that as nil.

type StoreEventFeed

type StoreEventFeed struct {
	// contains filtered or unexported fields
}

StoreEventFeed is a helper structure which publishes store-specific events to a util.Feed. The target feed may be shared by multiple StoreEventFeeds. If the target feed is nil, event methods become no-ops.

func NewStoreEventFeed

func NewStoreEventFeed(id proto.StoreID, feed *util.Feed) StoreEventFeed

NewStoreEventFeed creates a new StoreEventFeed which publishes events for a specific store to the supplied feed.

type StoreEventListener

type StoreEventListener interface {
	OnRegisterRange(event *RegisterRangeEvent)
	OnUpdateRange(event *UpdateRangeEvent)
	OnRemoveRange(event *RemoveRangeEvent)
	OnSplitRange(event *SplitRangeEvent)
	OnMergeRange(event *MergeRangeEvent)
	OnStartStore(event *StartStoreEvent)
	OnBeginScanRanges(event *BeginScanRangesEvent)
	OnEndScanRanges(event *EndScanRangesEvent)
	OnStoreStatus(event *StoreStatusEvent)
	OnReplicationStatus(event *ReplicationStatusEvent)
}

StoreEventListener is an interface that can be implemented by objects which listen for events published by stores.

type StoreStatus

type StoreStatus struct {
	Desc                 cockroach_proto.StoreDescriptor               `protobuf:"bytes,1,opt,name=desc" json:"desc"`
	NodeID               github_com_cockroachdb_cockroach_proto.NodeID `protobuf:"varint,2,opt,name=node_id,casttype=github.com/cockroachdb/cockroach/proto.NodeID" json:"node_id"`
	RangeCount           int32                                         `protobuf:"varint,3,opt,name=range_count" json:"range_count"`
	StartedAt            int64                                         `protobuf:"varint,4,opt,name=started_at" json:"started_at"`
	UpdatedAt            int64                                         `protobuf:"varint,5,opt,name=updated_at" json:"updated_at"`
	Stats                cockroach_storage_engine.MVCCStats            `protobuf:"bytes,6,opt,name=stats" json:"stats"`
	LeaderRangeCount     int32                                         `protobuf:"varint,7,opt,name=leader_range_count" json:"leader_range_count"`
	ReplicatedRangeCount int32                                         `protobuf:"varint,8,opt,name=replicated_range_count" json:"replicated_range_count"`
	AvailableRangeCount  int32                                         `protobuf:"varint,9,opt,name=available_range_count" json:"available_range_count"`
}

StoreStatus contains the stats needed to calculate the current status of a store.

func (*StoreStatus) GetAvailableRangeCount

func (m *StoreStatus) GetAvailableRangeCount() int32

func (*StoreStatus) GetDesc

func (*StoreStatus) GetLeaderRangeCount

func (m *StoreStatus) GetLeaderRangeCount() int32

func (*StoreStatus) GetNodeID

func (*StoreStatus) GetRangeCount

func (m *StoreStatus) GetRangeCount() int32

func (*StoreStatus) GetReplicatedRangeCount

func (m *StoreStatus) GetReplicatedRangeCount() int32

func (*StoreStatus) GetStartedAt

func (m *StoreStatus) GetStartedAt() int64

func (*StoreStatus) GetStats

func (*StoreStatus) GetUpdatedAt

func (m *StoreStatus) GetUpdatedAt() int64

func (*StoreStatus) Marshal

func (m *StoreStatus) Marshal() (data []byte, err error)

func (*StoreStatus) MarshalTo

func (m *StoreStatus) MarshalTo(data []byte) (int, error)

func (*StoreStatus) ProtoMessage

func (*StoreStatus) ProtoMessage()

func (*StoreStatus) Reset

func (m *StoreStatus) Reset()

func (*StoreStatus) Size

func (m *StoreStatus) Size() (n int)

func (*StoreStatus) String

func (m *StoreStatus) String() string

func (*StoreStatus) Unmarshal

func (m *StoreStatus) Unmarshal(data []byte) error

type StoreStatusEvent

type StoreStatusEvent struct {
	Desc *proto.StoreDescriptor
}

StoreStatusEvent contains the current descriptor for the given store.

Because the descriptor contains information that cannot currently be computed from other events, this event should be periodically broadcast by the store independently of other operations.

type TimestampCache

type TimestampCache struct {
	// contains filtered or unexported fields
}

A TimestampCache maintains an interval tree FIFO cache of keys or key ranges and the timestamps at which they were most recently read or written. If a timestamp was read or written by a transaction, the txn ID is stored with the timestamp to avoid advancing timestamps on successive requests from the same transaction.

The cache also maintains a low-water mark which is the most recently evicted entry's timestamp. This value always ratchets with monotonic increases. The low water mark is initialized to the current system time plus the maximum clock offset.

func NewTimestampCache

func NewTimestampCache(clock *hlc.Clock) *TimestampCache

NewTimestampCache returns a new timestamp cache with supplied hybrid clock.

func (*TimestampCache) Add

func (tc *TimestampCache) Add(start, end proto.Key, timestamp proto.Timestamp, txnID []byte, readOnly bool)

Add the specified timestamp to the cache as covering the range of keys from start to end. If end is nil, the range covers the start key only. txnID is nil for no transaction. readOnly specifies whether the command adding this timestamp was read-only or not.

func (*TimestampCache) Clear

func (tc *TimestampCache) Clear(clock *hlc.Clock)

Clear clears the cache and resets the low water mark to the current time plus the maximum clock offset.

func (*TimestampCache) GetMax

func (tc *TimestampCache) GetMax(start, end proto.Key, txnID []byte) (proto.Timestamp, proto.Timestamp)

GetMax returns the maximum read and write timestamps which overlap the interval spanning from start to end. Cached timestamps matching the specified txnID are not considered. If no part of the specified range is overlapped by timestamps in the cache, the low water timestamp is returned for both read and write timestamps.

The txn ID prevents restarts with a pattern like: read("a"), write("a"). The read adds a timestamp for "a". Then the write (for the same transaction) would get that as the max timestamp and be forced to increment it. This allows timestamps from the same txn to be ignored.

func (*TimestampCache) MergeInto

func (tc *TimestampCache) MergeInto(dest *TimestampCache, clear bool)

MergeInto merges all entries from this timestamp cache into the dest timestamp cache. The clear parameter, if true, copies the values of lowWater and latest and clears the destination cache before merging in the source.

func (*TimestampCache) SetLowWater

func (tc *TimestampCache) SetLowWater(lowWater proto.Timestamp)

SetLowWater sets the cache's low water mark, which is the minimum value the cache will return from calls to GetMax().

type UpdateRangeEvent

type UpdateRangeEvent struct {
	StoreID proto.StoreID
	Desc    *proto.RangeDescriptor
	Stats   engine.MVCCStats
	Method  proto.Method
	Delta   engine.MVCCStats
}

UpdateRangeEvent occurs whenever a Range is modified. This structure includes the basic range information, but also includes a second set of MVCCStats containing the delta from the Range's previous stats. If the update did not modify any statistics, this delta may be nil.

Directories

Path Synopsis
Package engine provides low-level storage.
Package engine provides low-level storage.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL