github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/kv/kvserver/stateloader/initial.go (about) 1 // Copyright 2016 The Cockroach Authors. 2 // 3 // Use of this software is governed by the Business Source License 4 // included in the file licenses/BSL.txt. 5 // 6 // As of the Change Date specified in that file, in accordance with 7 // the Business Source License, use of this software will be governed 8 // by the Apache License, Version 2.0, included in the file 9 // licenses/APL.txt. 10 11 package stateloader 12 13 import ( 14 "context" 15 16 "github.com/cockroachdb/cockroach/pkg/kv/kvserver/kvserverpb" 17 "github.com/cockroachdb/cockroach/pkg/roachpb" 18 "github.com/cockroachdb/cockroach/pkg/storage" 19 "github.com/cockroachdb/cockroach/pkg/storage/enginepb" 20 "github.com/cockroachdb/cockroach/pkg/util/hlc" 21 "github.com/cockroachdb/cockroach/pkg/util/log" 22 "github.com/cockroachdb/errors" 23 ) 24 25 // raftInitialLog{Index,Term} are the starting points for the raft log. We 26 // bootstrap the raft membership by synthesizing a snapshot as if there were 27 // some discarded prefix to the log, so we must begin the log at an arbitrary 28 // index greater than 1. 29 const ( 30 raftInitialLogIndex = 10 31 raftInitialLogTerm = 5 32 ) 33 34 // WriteInitialReplicaState sets up a new Range, but without writing an 35 // associated Raft state (which must be written separately via 36 // synthesizeRaftState before instantiating a Replica). The main task is to 37 // persist a ReplicaState which does not start from zero but presupposes a few 38 // entries already having applied. The supplied MVCCStats are used for the Stats 39 // field after adjusting for persisting the state itself, and the updated stats 40 // are returned. 41 func WriteInitialReplicaState( 42 ctx context.Context, 43 readWriter storage.ReadWriter, 44 ms enginepb.MVCCStats, 45 desc roachpb.RangeDescriptor, 46 lease roachpb.Lease, 47 gcThreshold hlc.Timestamp, 48 truncStateType TruncatedStateType, 49 ) (enginepb.MVCCStats, error) { 50 rsl := Make(desc.RangeID) 51 var s kvserverpb.ReplicaState 52 s.TruncatedState = &roachpb.RaftTruncatedState{ 53 Term: raftInitialLogTerm, 54 Index: raftInitialLogIndex, 55 } 56 s.RaftAppliedIndex = s.TruncatedState.Index 57 s.Desc = &roachpb.RangeDescriptor{ 58 RangeID: desc.RangeID, 59 } 60 s.Stats = &ms 61 s.Lease = &lease 62 s.GCThreshold = &gcThreshold 63 s.UsingAppliedStateKey = true 64 65 if existingLease, err := rsl.LoadLease(ctx, readWriter); err != nil { 66 return enginepb.MVCCStats{}, errors.Wrap(err, "error reading lease") 67 } else if (existingLease != roachpb.Lease{}) { 68 log.Fatalf(ctx, "expected trivial lease, but found %+v", existingLease) 69 } 70 71 if existingGCThreshold, err := rsl.LoadGCThreshold(ctx, readWriter); err != nil { 72 return enginepb.MVCCStats{}, errors.Wrap(err, "error reading GCThreshold") 73 } else if (*existingGCThreshold != hlc.Timestamp{}) { 74 log.Fatalf(ctx, "expected trivial GChreshold, but found %+v", existingGCThreshold) 75 } 76 77 newMS, err := rsl.Save(ctx, readWriter, s, truncStateType) 78 if err != nil { 79 return enginepb.MVCCStats{}, err 80 } 81 82 return newMS, nil 83 } 84 85 // WriteInitialState calls WriteInitialReplicaState followed by 86 // SynthesizeRaftState. It is typically called during bootstrap. The supplied 87 // MVCCStats are used for the Stats field after adjusting for persisting the 88 // state itself, and the updated stats are returned. 89 func WriteInitialState( 90 ctx context.Context, 91 readWriter storage.ReadWriter, 92 ms enginepb.MVCCStats, 93 desc roachpb.RangeDescriptor, 94 lease roachpb.Lease, 95 gcThreshold hlc.Timestamp, 96 truncStateType TruncatedStateType, 97 ) (enginepb.MVCCStats, error) { 98 newMS, err := WriteInitialReplicaState( 99 ctx, readWriter, ms, desc, lease, gcThreshold, truncStateType) 100 if err != nil { 101 return enginepb.MVCCStats{}, err 102 } 103 if err := Make(desc.RangeID).SynthesizeRaftState(ctx, readWriter); err != nil { 104 return enginepb.MVCCStats{}, err 105 } 106 return newMS, nil 107 }