func copySeqCache(e engine.Engine, srcID, dstID roachpb.RangeID, keyMin, keyMax engine.MVCCKey) error { var scratch [64]byte return e.Iterate(keyMin, keyMax, func(kv engine.MVCCKeyValue) (bool, error) { // Decode the key into a cmd, skipping on error. Otherwise, // write it to the corresponding key in the new cache. id, epoch, seq, err := decodeSequenceCacheMVCCKey(kv.Key, scratch[:0]) if err != nil { return false, util.Errorf("could not decode a sequence cache key %s: %s", kv.Key, err) } key := keys.SequenceCacheKey(dstID, id, epoch, seq) encKey := engine.MakeMVCCMetadataKey(key) // Decode the value, update the checksum and re-encode. meta := &engine.MVCCMetadata{} if err := proto.Unmarshal(kv.Value, meta); err != nil { return false, util.Errorf("could not decode sequence cache value %s [% x]: %s", kv.Key, kv.Value, err) } value := meta.Value() value.ClearChecksum() value.InitChecksum(key) meta.RawBytes = value.RawBytes _, _, err = engine.PutProto(e, encKey, meta) return false, err }) }
// 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 (rc *ResponseCache) CopyFrom(e engine.Engine, originRangeID proto.RangeID) error { prefix := keys.ResponseCacheKey(originRangeID, nil) // response cache prefix start := engine.MVCCEncodeKey(prefix) end := engine.MVCCEncodeKey(prefix.PrefixEnd()) return e.Iterate(start, end, func(kv proto.RawKeyValue) (bool, error) { // Decode the key into a cmd, skipping on error. Otherwise, // write it to the corresponding key in the new cache. cmdID, err := rc.decodeResponseCacheKey(kv.Key) if err != nil { return false, util.Errorf("could not decode a response cache key %s: %s", proto.Key(kv.Key), err) } key := keys.ResponseCacheKey(rc.rangeID, &cmdID) encKey := engine.MVCCEncodeKey(key) // Decode the value, update the checksum and re-encode. meta := &engine.MVCCMetadata{} if err := gogoproto.Unmarshal(kv.Value, meta); err != nil { return false, util.Errorf("could not decode response cache value %s [% x]: %s", proto.Key(kv.Key), kv.Value, err) } meta.Value.Checksum = nil meta.Value.InitChecksum(key) _, _, err = engine.PutProto(e, encKey, meta) return false, err }) }
// CopyInto copies all the cached results from this response cache // into the destRangeID response cache. Failures decoding individual // cache entries return an error. func (rc *ResponseCache) CopyInto(e engine.Engine, destRangeID roachpb.RangeID) error { start := engine.MVCCEncodeKey( keys.ResponseCacheKey(rc.rangeID, roachpb.KeyMin)) end := engine.MVCCEncodeKey( keys.ResponseCacheKey(rc.rangeID, roachpb.KeyMax)) return e.Iterate(start, end, func(kv engine.MVCCKeyValue) (bool, error) { // Decode the key into a cmd, skipping on error. Otherwise, // write it to the corresponding key in the new cache. family, err := rc.decodeResponseCacheKey(kv.Key) if err != nil { return false, util.Errorf("could not decode a response cache key %s: %s", roachpb.Key(kv.Key), err) } key := keys.ResponseCacheKey(destRangeID, family) encKey := engine.MVCCEncodeKey(key) // Decode the value, update the checksum and re-encode. meta := &engine.MVCCMetadata{} if err := proto.Unmarshal(kv.Value, meta); err != nil { return false, util.Errorf("could not decode response cache value %s [% x]: %s", roachpb.Key(kv.Key), kv.Value, err) } meta.Value.Checksum = nil meta.Value.InitChecksum(key) _, _, err = engine.PutProto(e, encKey, meta) return false, err }) }
// InternalTruncateLog discards a prefix of the raft log. func (r *Range) InternalTruncateLog(batch engine.Engine, ms *engine.MVCCStats, args *proto.InternalTruncateLogRequest, reply *proto.InternalTruncateLogResponse) { // args.Index is the first index to keep. term, err := r.Term(args.Index - 1) if err != nil { reply.SetGoError(err) return } start := keys.RaftLogKey(r.Desc().RaftID, 0) end := keys.RaftLogKey(r.Desc().RaftID, args.Index) err = batch.Iterate(engine.MVCCEncodeKey(start), engine.MVCCEncodeKey(end), func(kv proto.RawKeyValue) (bool, error) { err := batch.Clear(kv.Key) return false, err }) if err != nil { reply.SetGoError(err) return } ts := proto.RaftTruncatedState{ Index: args.Index - 1, Term: term, } err = engine.MVCCPutProto(batch, ms, keys.RaftTruncatedStateKey(r.Desc().RaftID), proto.ZeroTimestamp, nil, &ts) reply.SetGoError(err) }
func loadRangeDescriptor( db engine.Engine, rangeID roachpb.RangeID, ) (roachpb.RangeDescriptor, error) { var desc roachpb.RangeDescriptor handleKV := func(kv engine.MVCCKeyValue) (bool, error) { if kv.Key.Timestamp == hlc.ZeroTimestamp { // We only want values, not MVCCMetadata. return false, nil } if err := checkRangeDescriptorKey(kv.Key); err != nil { // Range descriptor keys are interleaved with others, so if it // doesn't parse as a range descriptor just skip it. return false, nil } if err := getProtoValue(kv.Value, &desc); err != nil { return false, err } return desc.RangeID == rangeID, nil } // Range descriptors are stored by key, so we have to scan over the // range-local data to find the one for this RangeID. start := engine.MakeMVCCMetadataKey(keys.LocalRangePrefix) end := engine.MakeMVCCMetadataKey(keys.LocalRangeMax) if err := db.Iterate(start, end, handleKV); err != nil { return roachpb.RangeDescriptor{}, err } if desc.RangeID == rangeID { return desc, nil } return roachpb.RangeDescriptor{}, fmt.Errorf("range descriptor %d not found", rangeID) }
// CopyFrom copies all the cached results from another 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 (rc *ResponseCache) CopyFrom(e engine.Engine, originRaftID int64) error { prefix := engine.ResponseCacheKey(originRaftID, nil) // response cache prefix start := engine.MVCCEncodeKey(prefix) end := engine.MVCCEncodeKey(prefix.PrefixEnd()) return e.Iterate(start, end, func(kv proto.RawKeyValue) (bool, error) { // Decode the key into a cmd, skipping on error. Otherwise, // write it to the corresponding key in the new cache. cmdID, err := rc.decodeResponseCacheKey(kv.Key) if err != nil { return false, util.Errorf("could not decode a response cache key %q: %s", kv.Key, err) } encKey := engine.MVCCEncodeKey(engine.ResponseCacheKey(rc.raftID, &cmdID)) return false, rc.engine.Put(encKey, kv.Value) }) }
func copySeqCache( e engine.Engine, ms *engine.MVCCStats, srcID, dstID roachpb.RangeID, keyMin, keyMax engine.MVCCKey, ) (int, error) { var scratch [64]byte var count int var meta engine.MVCCMetadata // TODO(spencer): look into making this an MVCCIteration and writing // the values using MVCC so we can avoid the ugliness of updating // the MVCCStats by hand below. err := e.Iterate(keyMin, keyMax, func(kv engine.MVCCKeyValue) (bool, error) { // Decode the key, skipping on error. Otherwise, write it to the // corresponding key in the new cache. txnID, err := decodeAbortCacheMVCCKey(kv.Key, scratch[:0]) if err != nil { return false, util.Errorf("could not decode an abort cache key %s: %s", kv.Key, err) } key := keys.AbortCacheKey(dstID, txnID) encKey := engine.MakeMVCCMetadataKey(key) // Decode the MVCCMetadata value. if err := proto.Unmarshal(kv.Value, &meta); err != nil { return false, util.Errorf("could not decode mvcc metadata %s [% x]: %s", kv.Key, kv.Value, err) } value := meta.Value() value.ClearChecksum() value.InitChecksum(key) meta.RawBytes = value.RawBytes keyBytes, valBytes, err := engine.PutProto(e, encKey, &meta) if err != nil { return false, err } count++ if ms != nil { ms.SysBytes += keyBytes + valBytes ms.SysCount++ } return false, nil }) return count, err }