本文整理汇总了Golang中github.com/cockroachdb/cockroach/storage/engine.MVCCGet函数的典型用法代码示例。如果您正苦于以下问题:Golang MVCCGet函数的具体用法?Golang MVCCGet怎么用?Golang MVCCGet使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了MVCCGet函数的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的Golang代码示例。
示例1: loadAppliedIndex
// loadAppliedIndex returns the Raft applied index and the lease applied index.
func loadAppliedIndex(
ctx context.Context, reader engine.Reader, rangeID roachpb.RangeID,
) (uint64, uint64, error) {
var appliedIndex uint64
v, _, err := engine.MVCCGet(ctx, reader, keys.RaftAppliedIndexKey(rangeID),
hlc.ZeroTimestamp, true, nil)
if err != nil {
return 0, 0, err
}
if v != nil {
int64AppliedIndex, err := v.GetInt()
if err != nil {
return 0, 0, err
}
appliedIndex = uint64(int64AppliedIndex)
}
// TODO(tschottdorf): code duplication.
var leaseAppliedIndex uint64
v, _, err = engine.MVCCGet(ctx, reader, keys.LeaseAppliedIndexKey(rangeID),
hlc.ZeroTimestamp, true, nil)
if err != nil {
return 0, 0, err
}
if v != nil {
int64LeaseAppliedIndex, err := v.GetInt()
if err != nil {
return 0, 0, err
}
leaseAppliedIndex = uint64(int64LeaseAppliedIndex)
}
return appliedIndex, leaseAppliedIndex, nil
}
开发者ID:yangxuanjia,项目名称:cockroach,代码行数:34,代码来源:replica_state.go
示例2: loadLastIndex
// loadLastIndex retrieves the last index from storage.
func loadLastIndex(eng engine.Reader, rangeID roachpb.RangeID, isInitialized bool) (uint64, error) {
lastIndex := uint64(0)
v, _, err := engine.MVCCGet(context.Background(), eng,
keys.RaftLastIndexKey(rangeID),
roachpb.ZeroTimestamp, true /* consistent */, nil)
if err != nil {
return 0, err
}
if v != nil {
int64LastIndex, err := v.GetInt()
if err != nil {
return 0, err
}
lastIndex = uint64(int64LastIndex)
} else {
// The log is empty, which means we are either starting from scratch
// or the entire log has been truncated away. raftTruncatedState
// handles both cases.
lastEnt, err := raftTruncatedState(eng, rangeID, isInitialized)
if err != nil {
return 0, err
}
lastIndex = lastEnt.Index
}
return lastIndex, nil
}
开发者ID:mjibson,项目名称:cockroach,代码行数:27,代码来源:replica_raftstorage.go
示例3: TestRejectFutureCommand
// TestRejectFutureCommand verifies that lease holders reject commands that
// would cause a large time jump.
func TestRejectFutureCommand(t *testing.T) {
defer leaktest.AfterTest(t)()
const maxOffset = 100 * time.Millisecond
manual := hlc.NewManualClock(0)
clock := hlc.NewClock(manual.UnixNano)
clock.SetMaxOffset(maxOffset)
mtc := multiTestContext{
clock: clock,
}
mtc.Start(t, 1)
defer mtc.Stop()
// First do a write. The first write will advance the clock by MaxOffset
// because of the read cache's low water mark.
getArgs := putArgs([]byte("b"), []byte("b"))
if _, err := client.SendWrapped(rg1(mtc.stores[0]), nil, &getArgs); err != nil {
t.Fatal(err)
}
if now := clock.Now(); now.WallTime != int64(maxOffset) {
t.Fatalf("expected clock to advance to 100ms; got %s", now)
}
// The logical clock has advanced past the physical clock; increment
// the "physical" clock to catch up.
manual.Increment(int64(maxOffset))
startTime := manual.UnixNano()
// Commands with a future timestamp that is within the MaxOffset
// bound will be accepted and will cause the clock to advance.
for i := int64(0); i < 3; i++ {
incArgs := incrementArgs([]byte("a"), 5)
ts := hlc.ZeroTimestamp.Add(startTime+((i+1)*30)*int64(time.Millisecond), 0)
if _, err := client.SendWrappedWith(rg1(mtc.stores[0]), nil, roachpb.Header{Timestamp: ts}, &incArgs); err != nil {
t.Fatal(err)
}
}
if now := clock.Now(); now.WallTime != int64(190*time.Millisecond) {
t.Fatalf("expected clock to advance to 190ms; got %s", now)
}
// Once the accumulated offset reaches MaxOffset, commands will be rejected.
incArgs := incrementArgs([]byte("a"), 11)
ts := hlc.ZeroTimestamp.Add(int64((time.Duration(startTime)+maxOffset+1)*time.Millisecond), 0)
if _, err := client.SendWrappedWith(rg1(mtc.stores[0]), nil, roachpb.Header{Timestamp: ts}, &incArgs); err == nil {
t.Fatalf("expected clock offset error but got nil")
}
// The clock remained at 190ms and the final command was not executed.
if now := clock.Now(); now.WallTime != int64(190*time.Millisecond) {
t.Errorf("expected clock to advance to 190ms; got %s", now)
}
val, _, err := engine.MVCCGet(context.Background(), mtc.engines[0], roachpb.Key("a"), clock.Now(), true, nil)
if err != nil {
t.Fatal(err)
}
if v := mustGetInt(val); v != 15 {
t.Errorf("expected 15, got %v", v)
}
}
开发者ID:yangxuanjia,项目名称:cockroach,代码行数:62,代码来源:client_replica_test.go
示例4: loadLastIndexLocked
// loadLastIndexLocked retrieves the last index from storage.
// loadLastIndexLocked requires that the replica lock is held.
func (r *Replica) loadLastIndexLocked() (uint64, error) {
lastIndex := uint64(0)
v, _, err := engine.MVCCGet(r.store.Engine(),
keys.RaftLastIndexKey(r.RangeID),
roachpb.ZeroTimestamp, true /* consistent */, nil)
if err != nil {
return 0, err
}
if v != nil {
int64LastIndex, err := v.GetInt()
if err != nil {
return 0, err
}
lastIndex = uint64(int64LastIndex)
} else {
// The log is empty, which means we are either starting from scratch
// or the entire log has been truncated away. raftTruncatedState
// handles both cases.
lastEnt, err := r.raftTruncatedStateLocked()
if err != nil {
return 0, err
}
lastIndex = lastEnt.Index
}
return lastIndex, nil
}
开发者ID:cuongdo,项目名称:cockroach,代码行数:28,代码来源:replica_raftstorage.go
示例5: loadLastIndex
func loadLastIndex(
ctx context.Context, reader engine.Reader, rangeID roachpb.RangeID,
) (uint64, error) {
lastIndex := uint64(0)
v, _, err := engine.MVCCGet(ctx, reader,
keys.RaftLastIndexKey(rangeID),
hlc.ZeroTimestamp, true /* consistent */, nil)
if err != nil {
return 0, err
}
if v != nil {
int64LastIndex, err := v.GetInt()
if err != nil {
return 0, err
}
lastIndex = uint64(int64LastIndex)
} else {
// The log is empty, which means we are either starting from scratch
// or the entire log has been truncated away.
lastEnt, err := loadTruncatedState(ctx, reader, rangeID)
if err != nil {
return 0, err
}
lastIndex = lastEnt.Index
}
return lastIndex, nil
}
开发者ID:yangxuanjia,项目名称:cockroach,代码行数:27,代码来源:replica_state.go
示例6: Get
// Get returns the value for a specified key.
func (r *Range) Get(batch engine.Engine, args proto.GetRequest) (proto.GetResponse, []proto.Intent, error) {
var reply proto.GetResponse
val, intents, err := engine.MVCCGet(batch, args.Key, args.Timestamp, args.ReadConsistency == proto.CONSISTENT, args.Txn)
reply.Value = val
return reply, intents, err
}
开发者ID:routhcr,项目名称:cockroach,代码行数:8,代码来源:range_command.go
示例7: loadLastIndex
// loadLastIndex retrieves the last index from storage.
func (r *Replica) loadLastIndex() (uint64, error) {
lastIndex := uint64(0)
v, _, err := engine.MVCCGet(r.rm.Engine(),
keys.RaftLastIndexKey(r.Desc().RangeID),
roachpb.ZeroTimestamp, true /* consistent */, nil)
if err != nil {
return 0, err
}
if v != nil {
var err error
_, lastIndex, err = encoding.DecodeUint64(v.GetRawBytes())
if err != nil {
return 0, err
}
} else {
// The log is empty, which means we are either starting from scratch
// or the entire log has been truncated away. raftTruncatedState
// handles both cases.
lastEnt, err := r.raftTruncatedState()
if err != nil {
return 0, err
}
lastIndex = lastEnt.Index
}
return lastIndex, nil
}
开发者ID:nporsche,项目名称:cockroach,代码行数:27,代码来源:replica_raftstorage.go
示例8: loadFrozenStatus
func loadFrozenStatus(reader engine.Reader, rangeID roachpb.RangeID) (bool, error) {
val, _, err := engine.MVCCGet(context.Background(), reader, keys.RangeFrozenStatusKey(rangeID),
hlc.ZeroTimestamp, true, nil)
if err != nil {
return false, err
}
if val == nil {
return false, nil
}
return val.GetBool()
}
开发者ID:CubeLite,项目名称:cockroach,代码行数:11,代码来源:replica_state.go
示例9: TestRangeCommandClockUpdate
// TestRangeCommandClockUpdate verifies that followers update their
// clocks when executing a command, even if the lease holder's clock is far
// in the future.
func TestRangeCommandClockUpdate(t *testing.T) {
defer leaktest.AfterTest(t)()
const numNodes = 3
var manuals []*hlc.ManualClock
var clocks []*hlc.Clock
for i := 0; i < numNodes; i++ {
manuals = append(manuals, hlc.NewManualClock(1))
clocks = append(clocks, hlc.NewClock(manuals[i].UnixNano))
clocks[i].SetMaxOffset(100 * time.Millisecond)
}
mtc := multiTestContext{
clocks: clocks,
}
mtc.Start(t, numNodes)
defer mtc.Stop()
mtc.replicateRange(1, 1, 2)
// Advance the lease holder's clock ahead of the followers (by more than
// MaxOffset but less than the range lease) and execute a command.
manuals[0].Increment(int64(500 * time.Millisecond))
incArgs := incrementArgs([]byte("a"), 5)
ts := clocks[0].Now()
if _, err := client.SendWrappedWith(rg1(mtc.stores[0]), nil, roachpb.Header{Timestamp: ts}, &incArgs); err != nil {
t.Fatal(err)
}
// Wait for that command to execute on all the followers.
util.SucceedsSoon(t, func() error {
values := []int64{}
for _, eng := range mtc.engines {
val, _, err := engine.MVCCGet(context.Background(), eng, roachpb.Key("a"), clocks[0].Now(), true, nil)
if err != nil {
return err
}
values = append(values, mustGetInt(val))
}
if !reflect.DeepEqual(values, []int64{5, 5, 5}) {
return errors.Errorf("expected (5, 5, 5), got %v", values)
}
return nil
})
// Verify that all the followers have accepted the clock update from
// node 0 even though it comes from outside the usual max offset.
now := clocks[0].Now()
for i, clock := range clocks {
// Only compare the WallTimes: it's normal for clock 0 to be a few logical ticks ahead.
if clock.Now().WallTime < now.WallTime {
t.Errorf("clock %d is behind clock 0: %s vs %s", i, clock.Now(), now)
}
}
}
开发者ID:yangxuanjia,项目名称:cockroach,代码行数:56,代码来源:client_replica_test.go
示例10: GetSequence
// GetSequence looks up the latest sequence number recorded for this family. On a
// cache miss, zero is returned.
func (rc *ResponseCache) GetSequence(e engine.Engine, family []byte) (int64, error) {
if len(family) == 0 {
return 0, errEmptyID
}
// Pull response from the cache and read into reply if available.
key := keys.ResponseCacheKey(rc.rangeID, family)
v, _, err := engine.MVCCGet(e, key, roachpb.ZeroTimestamp, true, nil)
if err != nil {
return 0, err
}
if v == nil {
return 0, nil
}
return v.GetInt()
}
开发者ID:xujun10110,项目名称:cockroach,代码行数:18,代码来源:response_cache.go
示例11: TestProgressWithDownNode
// TestProgressWithDownNode verifies that a surviving quorum can make progress
// with a downed node.
func TestProgressWithDownNode(t *testing.T) {
defer leaktest.AfterTest(t)
mtc := startMultiTestContext(t, 3)
defer mtc.Stop()
rangeID := roachpb.RangeID(1)
mtc.replicateRange(rangeID, 1, 2)
incArgs := incrementArgs([]byte("a"), 5)
if _, err := client.SendWrapped(rg1(mtc.stores[0]), nil, &incArgs); err != nil {
t.Fatal(err)
}
// Verify that the first increment propagates to all the engines.
verify := func(expected []int64) {
util.SucceedsWithin(t, time.Second, func() error {
values := []int64{}
for _, eng := range mtc.engines {
val, _, err := engine.MVCCGet(eng, roachpb.Key("a"), mtc.clock.Now(), true, nil)
if err != nil {
return err
}
values = append(values, mustGetInt(val))
}
if !reflect.DeepEqual(expected, values) {
return util.Errorf("expected %v, got %v", expected, values)
}
return nil
})
}
verify([]int64{5, 5, 5})
// Stop one of the replicas and issue a new increment.
mtc.stopStore(1)
incArgs = incrementArgs([]byte("a"), 11)
if _, err := client.SendWrapped(rg1(mtc.stores[0]), nil, &incArgs); err != nil {
t.Fatal(err)
}
// The new increment can be seen on both live replicas.
verify([]int64{16, 5, 16})
// Once the downed node is restarted, it will catch up.
mtc.restartStore(1)
verify([]int64{16, 16, 16})
}
开发者ID:harryge00,项目名称:cockroach,代码行数:48,代码来源:client_raft_test.go
示例12: loadAppliedIndex
// loadAppliedIndex retrieves the applied index from the supplied engine.
func (r *Range) loadAppliedIndex(eng engine.Engine) (uint64, error) {
var appliedIndex uint64
if r.isInitialized() {
appliedIndex = raftInitialLogIndex
} else {
appliedIndex = 0
}
v, _, err := engine.MVCCGet(eng, keys.RaftAppliedIndexKey(r.Desc().RaftID),
proto.ZeroTimestamp, true, nil)
if err != nil {
return 0, err
}
if v != nil {
_, appliedIndex = encoding.DecodeUint64(v.Bytes)
}
return appliedIndex, nil
}
开发者ID:Hellblazer,项目名称:cockroach,代码行数:18,代码来源:range_raftstorage.go
示例13: loadAppliedIndex
// loadAppliedIndex retrieves the applied index from the supplied engine.
func (r *Replica) loadAppliedIndex(eng engine.Engine) (uint64, error) {
var appliedIndex uint64
if r.isInitialized() {
appliedIndex = raftInitialLogIndex
} else {
appliedIndex = 0
}
v, _, err := engine.MVCCGet(eng, keys.RaftAppliedIndexKey(r.Desc().RangeID),
roachpb.ZeroTimestamp, true, nil)
if err != nil {
return 0, err
}
if v != nil {
var err error
_, appliedIndex, err = encoding.DecodeUint64(v.GetRawBytes())
if err != nil {
return 0, err
}
}
return appliedIndex, nil
}
开发者ID:nporsche,项目名称:cockroach,代码行数:22,代码来源:replica_raftstorage.go
示例14: loadAppliedIndex
// loadAppliedIndex retrieves the applied index from the supplied engine.
func loadAppliedIndex(eng engine.Reader, rangeID roachpb.RangeID, isInitialized bool) (uint64, error) {
var appliedIndex uint64
if isInitialized {
appliedIndex = raftInitialLogIndex
} else {
appliedIndex = 0
}
v, _, err := engine.MVCCGet(context.Background(), eng, keys.RaftAppliedIndexKey(rangeID),
roachpb.ZeroTimestamp, true, nil)
if err != nil {
return 0, err
}
if v != nil {
int64AppliedIndex, err := v.GetInt()
if err != nil {
return 0, err
}
appliedIndex = uint64(int64AppliedIndex)
}
return appliedIndex, nil
}
开发者ID:mjibson,项目名称:cockroach,代码行数:22,代码来源:replica_raftstorage.go
示例15: loadAppliedIndexLocked
// loadAppliedIndexLocked retrieves the applied index from the supplied engine.
// loadAppliedIndexLocked requires that the replica lock is held.
func (r *Replica) loadAppliedIndexLocked(eng engine.Engine) (uint64, error) {
var appliedIndex uint64
if r.isInitializedLocked() {
appliedIndex = raftInitialLogIndex
} else {
appliedIndex = 0
}
v, _, err := engine.MVCCGet(eng, keys.RaftAppliedIndexKey(r.RangeID),
roachpb.ZeroTimestamp, true, nil)
if err != nil {
return 0, err
}
if v != nil {
int64AppliedIndex, err := v.GetInt()
if err != nil {
return 0, err
}
appliedIndex = uint64(int64AppliedIndex)
}
return appliedIndex, nil
}
开发者ID:cuongdo,项目名称:cockroach,代码行数:23,代码来源:replica_raftstorage.go
示例16: TestStoreRangeMergeWithData
// TestStoreRangeMergeWithData attempts to merge two collocate ranges
// each containing data.
func TestStoreRangeMergeWithData(t *testing.T) {
defer leaktest.AfterTest(t)
content := roachpb.Key("testing!")
store, stopper := createTestStore(t)
defer stopper.Stop()
aDesc, bDesc, err := createSplitRanges(store)
if err != nil {
t.Fatal(err)
}
// Write some values left and right of the proposed split key.
pArgs := putArgs([]byte("aaa"), content)
if _, err := client.SendWrapped(rg1(store), nil, &pArgs); err != nil {
t.Fatal(err)
}
pArgs = putArgs([]byte("ccc"), content)
if _, err := client.SendWrappedWith(rg1(store), nil, roachpb.Header{
RangeID: bDesc.RangeID,
}, &pArgs); err != nil {
t.Fatal(err)
}
// Confirm the values are there.
gArgs := getArgs([]byte("aaa"))
if reply, err := client.SendWrapped(rg1(store), nil, &gArgs); err != nil {
t.Fatal(err)
} else if replyBytes, err := reply.(*roachpb.GetResponse).Value.GetBytes(); err != nil {
t.Fatal(err)
} else if !bytes.Equal(replyBytes, content) {
t.Fatalf("actual value %q did not match expected value %q", replyBytes, content)
}
gArgs = getArgs([]byte("ccc"))
if reply, err := client.SendWrappedWith(rg1(store), nil, roachpb.Header{
RangeID: bDesc.RangeID,
}, &gArgs); err != nil {
t.Fatal(err)
} else if replyBytes, err := reply.(*roachpb.GetResponse).Value.GetBytes(); err != nil {
t.Fatal(err)
} else if !bytes.Equal(replyBytes, content) {
t.Fatalf("actual value %q did not match expected value %q", replyBytes, content)
}
// Merge the b range back into the a range.
args := adminMergeArgs(roachpb.KeyMin)
if _, err := client.SendWrapped(rg1(store), nil, &args); err != nil {
t.Fatal(err)
}
// Verify no intents remains on range descriptor keys.
for _, key := range []roachpb.Key{keys.RangeDescriptorKey(aDesc.StartKey), keys.RangeDescriptorKey(bDesc.StartKey)} {
if _, _, err := engine.MVCCGet(store.Engine(), key, store.Clock().Now(), true, nil); err != nil {
t.Fatal(err)
}
}
// Verify the merge by looking up keys from both ranges.
rangeA := store.LookupReplica([]byte("a"), nil)
rangeB := store.LookupReplica([]byte("c"), nil)
rangeADesc := rangeA.Desc()
rangeBDesc := rangeB.Desc()
if !reflect.DeepEqual(rangeA, rangeB) {
t.Fatalf("ranges were not merged %+v=%+v", rangeADesc, rangeBDesc)
}
if !bytes.Equal(rangeADesc.StartKey, roachpb.RKeyMin) {
t.Fatalf("The start key is not equal to KeyMin %q=%q", rangeADesc.StartKey, roachpb.RKeyMin)
}
if !bytes.Equal(rangeADesc.EndKey, roachpb.RKeyMax) {
t.Fatalf("The end key is not equal to KeyMax %q=%q", rangeADesc.EndKey, roachpb.RKeyMax)
}
// Try to get values from after the merge.
gArgs = getArgs([]byte("aaa"))
if reply, err := client.SendWrapped(rg1(store), nil, &gArgs); err != nil {
t.Fatal(err)
} else if replyBytes, err := reply.(*roachpb.GetResponse).Value.GetBytes(); err != nil {
t.Fatal(err)
} else if !bytes.Equal(replyBytes, content) {
t.Fatalf("actual value %q did not match expected value %q", replyBytes, content)
}
gArgs = getArgs([]byte("ccc"))
if reply, err := client.SendWrappedWith(rg1(store), nil, roachpb.Header{
RangeID: rangeB.RangeID,
}, &gArgs); err != nil {
t.Fatal(err)
} else if replyBytes, err := reply.(*roachpb.GetResponse).Value.GetBytes(); err != nil {
t.Fatal(err)
} else if !bytes.Equal(replyBytes, content) {
t.Fatalf("actual value %q did not match expected value %q", replyBytes, content)
}
// Put new values after the merge on both sides.
pArgs = putArgs([]byte("aaaa"), content)
if _, err := client.SendWrapped(rg1(store), nil, &pArgs); err != nil {
t.Fatal(err)
}
//.........这里部分代码省略.........
开发者ID:leonllyu,项目名称:cockroach,代码行数:101,代码来源:client_merge_test.go
示例17: ApplySnapshot
// ApplySnapshot implements the multiraft.WriteableGroupStorage interface.
func (r *Range) ApplySnapshot(snap raftpb.Snapshot) error {
snapData := proto.RaftSnapshotData{}
err := gogoproto.Unmarshal(snap.Data, &snapData)
if err != nil {
return err
}
// First, save the HardState. The HardState must not be changed
// because it may record a previous vote cast by this node.
hardStateKey := keys.RaftHardStateKey(r.Desc().RaftID)
hardState, _, err := engine.MVCCGet(r.rm.Engine(), hardStateKey, proto.ZeroTimestamp, true /* consistent */, nil)
if err != nil {
return err
}
// Extract the updated range descriptor.
desc := snapData.RangeDescriptor
batch := r.rm.Engine().NewBatch()
defer batch.Close()
// Delete everything in the range and recreate it from the snapshot.
for iter := newRangeDataIterator(&desc, r.rm.Engine()); iter.Valid(); iter.Next() {
if err := batch.Clear(iter.Key()); err != nil {
return err
}
}
// Write the snapshot into the range.
for _, kv := range snapData.KV {
if err := batch.Put(kv.Key, kv.Value); err != nil {
return err
}
}
// Restore the saved HardState.
if hardState == nil {
err := engine.MVCCDelete(batch, nil, hardStateKey, proto.ZeroTimestamp, nil)
if err != nil {
return err
}
} else {
err := engine.MVCCPut(batch, nil, hardStateKey, proto.ZeroTimestamp, *hardState, nil)
if err != nil {
return err
}
}
// Read the leader lease.
lease, err := loadLeaderLease(batch, desc.RaftID)
if err != nil {
return err
}
// Copy range stats to new range.
oldStats := r.stats
r.stats, err = newRangeStats(desc.RaftID, batch)
if err != nil {
r.stats = oldStats
return err
}
// The next line sets the persisted last index to the last applied index.
// This is not a correctness issue, but means that we may have just
// transferred some entries we're about to re-request from the leader and
// overwrite.
// However, raft.MultiNode currently expects this behaviour, and the
// performance implications are not likely to be drastic. If our feelings
// about this ever change, we can add a LastIndex field to
// raftpb.SnapshotMetadata.
if err := setLastIndex(batch, r.Desc().RaftID, snap.Metadata.Index); err != nil {
return err
}
if err := batch.Commit(); err != nil {
return err
}
// As outlined above, last and applied index are the same after applying
// the snapshot.
atomic.StoreUint64(&r.lastIndex, snap.Metadata.Index)
atomic.StoreUint64(&r.appliedIndex, snap.Metadata.Index)
// Atomically update the descriptor and lease.
if err := r.setDesc(&desc); err != nil {
return err
}
atomic.StorePointer(&r.lease, unsafe.Pointer(lease))
return nil
}
开发者ID:Hellblazer,项目名称:cockroach,代码行数:91,代码来源:range_raftstorage.go
示例18: applySnapshot
// applySnapshot updates the replica based on the given snapshot.
func (r *Replica) applySnapshot(snap raftpb.Snapshot) error {
snapData := roachpb.RaftSnapshotData{}
err := proto.Unmarshal(snap.Data, &snapData)
if err != nil {
return err
}
rangeID := r.Desc().RangeID
// First, save the HardState. The HardState must not be changed
// because it may record a previous vote cast by this node.
hardStateKey := keys.RaftHardStateKey(rangeID)
hardState, _, err := engine.MVCCGet(r.store.Engine(), hardStateKey, roachpb.ZeroTimestamp, true /* consistent */, nil)
if err != nil {
return err
}
// Extract the updated range descriptor.
desc := snapData.RangeDescriptor
batch := r.store.Engine().NewBatch()
defer batch.Close()
// Delete everything in the range and recreate it from the snapshot.
iter := newReplicaDataIterator(&desc, r.store.Engine())
defer iter.Close()
for ; iter.Valid(); iter.Next() {
if err := batch.Clear(iter.Key()); err != nil {
return err
}
}
// Write the snapshot into the range.
for _, kv := range snapData.KV {
mvccKey := engine.MVCCKey{
Key: kv.Key,
Timestamp: kv.Timestamp,
}
if err := batch.Put(mvccKey, kv.Value); err != nil {
return err
}
}
// Restore the saved HardState.
if hardState == nil {
err := engine.MVCCDelete(batch, nil, hardStateKey, roachpb.ZeroTimestamp, nil)
if err != nil {
return err
}
} else {
err := engine.MVCCPut(batch, nil, hardStateKey, roachpb.ZeroTimestamp, *hardState, nil)
if err != nil {
return err
}
}
// Read the leader lease.
lease, err := loadLeaderLease(batch, desc.RangeID)
if err != nil {
return err
}
// Load updated range stats. The local newStats variable will be assigned
// to r.stats after the batch commits.
newStats, err := newRangeStats(desc.RangeID, batch)
if err != nil {
return err
}
// The next line sets the persisted last index to the last applied index.
// This is not a correctness issue, but means that we may have just
// transferred some entries we're about to re-request from the leader and
// overwrite.
// However, raft.MultiNode currently expects this behaviour, and the
// performance implications are not likely to be drastic. If our feelings
// about this ever change, we can add a LastIndex field to
// raftpb.SnapshotMetadata.
if err := setLastIndex(batch, rangeID, snap.Metadata.Index); err != nil {
return err
}
if err := batch.Commit(); err != nil {
return err
}
// Update the range stats.
r.stats.Replace(newStats)
// As outlined above, last and applied index are the same after applying
// the snapshot.
atomic.StoreUint64(&r.lastIndex, snap.Metadata.Index)
atomic.StoreUint64(&r.appliedIndex, snap.Metadata.Index)
// Atomically update the descriptor and lease.
if err := r.setDesc(&desc); err != nil {
return err
}
// Update other fields which are uninitialized or need updating.
// This may not happen if the system config has not yet been loaded.
//.........这里部分代码省略.........
开发者ID:kaustubhkurve,项目名称:cockroach,代码行数:101,代码来源:replica_raftstorage.go
示例19: TestReplicateAddAndRemove
func TestReplicateAddAndRemove(t *testing.T) {
defer leaktest.AfterTest(t)
testFunc := func(addFirst bool) {
mtc := startMultiTestContext(t, 4)
defer mtc.Stop()
// Replicate the initial range to three of the four nodes.
rangeID := roachpb.RangeID(1)
mtc.replicateRange(rangeID, 3, 1)
incArgs := incrementArgs([]byte("a"), 5)
if _, err := client.SendWrapped(rg1(mtc.stores[0]), nil, &incArgs); err != nil {
t.Fatal(err)
}
verify := func(expected []int64) {
util.SucceedsWithin(t, 3*time.Second, func() error {
values := []int64{}
for _, eng := range mtc.engines {
val, _, err := engine.MVCCGet(eng, roachpb.Key("a"), mtc.clock.Now(), true, nil)
if err != nil {
return err
}
values = append(values, mustGetInt(val))
}
if !reflect.DeepEqual(expected, values) {
return util.Errorf("addFirst: %t, expected %v, got %v", addFirst, expected, values)
}
return nil
})
}
// The first increment is visible on all three replicas.
verify([]int64{5, 5, 0, 5})
// Stop a store and replace it.
mtc.stopStore(1)
if addFirst {
mtc.replicateRange(rangeID, 2)
mtc.unreplicateRange(rangeID, 1)
} else {
mtc.unreplicateRange(rangeID, 1)
mtc.replicateRange(rangeID, 2)
}
verify([]int64{5, 5, 5, 5})
// Ensure that the rest of the group can make progress.
incArgs = incrementArgs([]byte("a"), 11)
if _, err := client.SendWrapped(rg1(mtc.stores[0]), nil, &incArgs); err != nil {
t.Fatal(err)
}
verify([]int64{16, 5, 16, 16})
// Bring the downed store back up (required for a clean shutdown).
mtc.restartStore(1)
// Node 1 never sees the increment that was added while it was
// down. Perform another increment on the live nodes to verify.
incArgs = incrementArgs([]byte("a"), 23)
if _, err := client.SendWrapped(rg1(mtc.stores[0]), nil, &incArgs); err != nil {
t.Fatal(err)
}
verify([]int64{39, 5, 39, 39})
// Wait out the leader lease and the unleased duration to make the replica GC'able.
mtc.manualClock.Increment(int64(storage.ReplicaGCQueueInactivityThreshold+storage.DefaultLeaderLeaseDuration) + 1)
mtc.stores[1].ForceReplicaGCScanAndProcess()
// The removed store no longer has any of the data from the range.
verify([]int64{39, 0, 39, 39})
desc := mtc.stores[0].LookupReplica(roachpb.RKeyMin, nil).Desc()
replicaIDsByStore := map[roachpb.StoreID]roachpb.ReplicaID{}
for _, rep := range desc.Replicas {
replicaIDsByStore[rep.StoreID] = rep.ReplicaID
}
expected := map[roachpb.StoreID]roachpb.ReplicaID{1: 1, 4: 2, 3: 4}
if !reflect.DeepEqual(expected, replicaIDsByStore) {
t.Fatalf("expected replica IDs to be %v but got %v", expected, replicaIDsByStore)
}
}
// Run the test twice, once adding the replacement before removing
// the downed node, and once removing the downed node first.
testFunc(true)
testFunc(false)
}
开发者ID:harryge00,项目名称:cockroach,代码行数:87,代码来源:client_raft_test.go
示例20: TestStoreRangeMergeWithData
// TestStoreRangeMergeWithData attempts to merge two collocate ranges
// each containing data.
func TestStoreRangeMergeWithData(t *testing.T) {
defer leaktest.AfterTest(t)
content := proto.Key("testing!")
store, stopper := createTestStore(t)
defer stopper.Stop()
aDesc, bDesc, err := createSplitRanges(store)
if err != nil {
t.Fatal(err)
}
// Write some values left and right of the proposed split key.
pArgs := putArgs([]byte("aaa"), content, aDesc.RangeID, store.StoreID())
if _, err := store.ExecuteCmd(context.Background(), &pArgs); err != nil {
t.Fatal(err)
}
pArgs = putArgs([]byte("ccc"), content, bDesc.RangeID, store.StoreID())
if _, err := store.ExecuteCmd(context.Background(), &pArgs); err != nil {
t.Fatal(err)
}
// Confirm the values are there.
gArgs := getArgs([]byte("aaa"), aDesc.RangeID, store.StoreID())
if reply, err := store.ExecuteCmd(context.Background(), &gArgs); err != nil {
t.Fatal(err)
} else if gReply := reply.(*proto.GetResponse); !bytes.Equal(gReply.Value.Bytes, content) {
t.Fatalf("actual value %q did not match expected value %q", gReply.Value.Bytes, content)
}
gArgs = getArgs([]byte("ccc"), bDesc.RangeID, store.StoreID())
if reply, err := store.ExecuteCmd(context.Background(), &gArgs); err != nil {
t.Fatal(err)
} else if gReply := reply.(*proto.GetResponse); !bytes.Equal(gReply.Value.Bytes, content) {
t.Fatalf("actual value %q did not match expected value %q", gReply.Value.Bytes, content)
}
// Merge the b range back into the a range.
args := adminMergeArgs(proto.KeyMin, 1, store.StoreID())
if _, err := store.ExecuteCmd(context.Background(), &args); err != nil {
t.Fatal(err)
}
// Verify no intents remains on range descriptor keys.
for _, key := range []proto.Key{keys.RangeDescriptorKey(aDesc.StartKey), keys.RangeDescriptorKey(bDesc.StartKey)} {
if _, _, err := engine.MVCCGet(store.Engine(), key, store.Clock().Now(), true, nil); err != nil {
t.Fatal(err)
}
}
// Verify the merge by looking up keys from both ranges.
rangeA := store.LookupRange([]byte("a"), nil)
rangeB := store.LookupRange([]byte("c"), nil)
if !reflect.DeepEqual(rangeA, rangeB) {
t.Fatalf("ranges were not merged %+v=%+v", rangeA.Desc(), rangeB.Desc())
}
if !bytes.Equal(rangeA.Desc().StartKey, proto.KeyMin) {
t.Fatalf("The start key is not equal to KeyMin %q=%q", rangeA.Desc().StartKey, proto.KeyMin)
}
if !bytes.Equal(rangeA.Desc().EndKey, proto.KeyMax) {
t.Fatalf("The end key is not equal to KeyMax %q=%q", rangeA.Desc().EndKey, proto.KeyMax)
}
// Try to get values from after the merge.
gArgs = getArgs([]byte("aaa"), rangeA.Desc().RangeID, store.StoreID())
if reply, err := store.ExecuteCmd(context.Background(), &gArgs); err != nil {
t.Fatal(err)
} else if gReply := reply.(*proto.GetResponse); !bytes.Equal(gReply.Value.Bytes, content) {
t.Fatalf("actual value %q did not match expected value %q", gReply.Value.Bytes, content)
}
gArgs = getArgs([]byte("ccc"), rangeB.Desc().RangeID, store.StoreID())
if reply, err := store.ExecuteCmd(context.Background(), &gArgs); err != nil {
t.Fatal(err)
} else if gReply := reply.(*proto.GetResponse); !bytes.Equal(gReply.Value.Bytes, content) {
t.Fatalf("actual value %q did not match expected value %q", gReply.Value.Bytes, content)
}
// Put new values after the merge on both sides.
pArgs = putArgs([]byte("aaaa"), content, rangeA.Desc().RangeID, store.StoreID())
if _, err = store.ExecuteCmd(context.Background(), &pArgs); err != nil {
t.Fatal(err)
}
pArgs = putArgs([]byte("cccc"), content, rangeB.Desc().RangeID, store.StoreID())
if _, err = store.ExecuteCmd(context.Background(), &pArgs); err != nil {
t.Fatal(err)
}
// Try to get the newly placed values.
gArgs = getArgs([]byte("aaaa"), rangeA.Desc().RangeID, store.StoreID())
if reply, err := store.ExecuteCmd(context.Background(), &gArgs); err != nil {
t.Fatal(err)
} else if gReply := reply.(*proto.GetResponse); !bytes.Equal(gReply.Value.Bytes, content) {
t.Fatalf("actual value %q did not match expected value %q", gReply.Value.Bytes, content)
}
gArgs = getArgs([]byte("cccc"), rangeA.Desc().RangeID, store.StoreID())
if reply, err := store.ExecuteCmd(context.Background(), &gArgs); err != nil {
t.Fatal(err)
} else if gReply := reply.(*proto.GetResponse); !bytes.Equal(gReply.Value.Bytes, content) {
//.........这里部分代码省略.........
开发者ID:arypurnomoz,项目名称:cockroach,代码行数:101,代码来源:client_merge_test.go
注:本文中的github.com/cockroachdb/cockroach/storage/engine.MVCCGet函数示例整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。 |
请发表评论