// ComputeStatsForRange computes the stats for a given range by // iterating over all key ranges for the given range that should // be accounted for in its stats. func ComputeStatsForRange( d *roachpb.RangeDescriptor, e engine.Reader, nowNanos int64, ) (enginepb.MVCCStats, error) { iter := e.NewIterator(false) defer iter.Close() ms := enginepb.MVCCStats{} for _, r := range makeReplicatedKeyRanges(d) { msDelta, err := iter.ComputeStats(r.start, r.end, nowNanos) if err != nil { return enginepb.MVCCStats{}, err } ms.Add(msDelta) } return ms, nil }
// ComputeMVCCStats immediately computes correct total MVCC usage statistics // for the store, returning the computed values (but without modifying the // store). func (s *Store) ComputeMVCCStats() (enginepb.MVCCStats, error) { var totalStats enginepb.MVCCStats var err error now := s.Clock().PhysicalNow() newStoreReplicaVisitor(s).Visit(func(r *Replica) bool { var stats enginepb.MVCCStats stats, err = ComputeStatsForRange(r.Desc(), s.Engine(), now) if err != nil { return false } totalStats.Add(stats) return true }) return totalStats, err }
func copySeqCache( e engine.ReadWriter, ms *enginepb.MVCCStats, srcID, dstID roachpb.RangeID, keyMin, keyMax engine.MVCCKey, ) (int, error) { var scratch [64]byte var count int var meta enginepb.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, errors.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, errors.Errorf("could not decode mvcc metadata %s [% x]: %s", kv.Key, kv.Value, err) } value := engine.MakeValue(meta) 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 }
func (r *rocksDBIterator) ComputeStats( start, end MVCCKey, nowNanos int64, ) (enginepb.MVCCStats, error) { result := C.MVCCComputeStats(r.iter, goToCKey(start), goToCKey(end), C.int64_t(nowNanos)) ms := enginepb.MVCCStats{} if err := statusToError(result.status); err != nil { return ms, err } ms.ContainsEstimates = false ms.LiveBytes = int64(result.live_bytes) ms.KeyBytes = int64(result.key_bytes) ms.ValBytes = int64(result.val_bytes) ms.IntentBytes = int64(result.intent_bytes) ms.LiveCount = int64(result.live_count) ms.KeyCount = int64(result.key_count) ms.ValCount = int64(result.val_count) ms.IntentCount = int64(result.intent_count) ms.IntentAge = int64(result.intent_age) ms.GCBytesAge = int64(result.gc_bytes_age) ms.SysBytes = int64(result.sys_bytes) ms.SysCount = int64(result.sys_count) ms.LastUpdateNanos = nowNanos return ms, nil }