@@ -7426,6 +7426,52 @@ func computeStatsForIterWithVisitors(
7426
7426
implicitMeta := isValue && ! bytes .Equal (unsafeKey .Key , prevKey )
7427
7427
prevKey = append (prevKey [:0 ], unsafeKey .Key ... )
7428
7428
7429
+ if ! isValue {
7430
+ // The key-value is not a MVCC value (i.e., the key has a zero
7431
+ // timestamp). The stats accounting for non-MVCC values is simpler.
7432
+ metaKeySize := int64 (len (unsafeKey .Key )) + 1
7433
+ metaValSize := int64 (iter .ValueLen ())
7434
+ totalBytes := metaKeySize + metaValSize
7435
+ first = true
7436
+
7437
+ if isSys {
7438
+ // The key is an internal system key. It contributes to
7439
+ // Sys{Bytes,Count} instead of {Key,Val}{Count,Bytes}.
7440
+ ms .SysBytes += totalBytes
7441
+ ms .SysCount ++
7442
+ if isAbortSpanKey (unsafeKey .Key ) {
7443
+ ms .AbortSpanBytes += totalBytes
7444
+ }
7445
+ continue
7446
+ }
7447
+ // A non-system key. Decode the value as a MVCCMetadata.
7448
+ v , err := iter .UnsafeValue ()
7449
+ if err != nil {
7450
+ return enginepb.MVCCStats {}, err
7451
+ }
7452
+ if err := protoutil .Unmarshal (v , & meta ); err != nil {
7453
+ return ms , errors .Wrap (err , "unable to decode MVCCMetadata" )
7454
+ }
7455
+ if meta .Deleted {
7456
+ // First value is deleted, so it's GC'able; add meta key & value
7457
+ // bytes to age stat.
7458
+ ms .GCBytesAge += totalBytes * (nowNanos / 1e9 - meta .Timestamp .WallTime / 1e9 )
7459
+ } else {
7460
+ ms .LiveBytes += totalBytes
7461
+ ms .LiveCount ++
7462
+ }
7463
+ ms .KeyBytes += metaKeySize
7464
+ ms .ValBytes += metaValSize
7465
+ ms .KeyCount ++
7466
+ if meta .IsInline () {
7467
+ ms .ValCount ++
7468
+ }
7469
+ continue
7470
+ }
7471
+
7472
+ // The key-value is a MVCC value (i.e., the key has a non-zero
7473
+ // timestamp).
7474
+
7429
7475
// Find the closest range tombstone above the point key. Range tombstones
7430
7476
// cannot exist above intents, and are undefined across inline values, so we
7431
7477
// only take them into account for versioned values.
@@ -7435,25 +7481,15 @@ func computeStatsForIterWithVisitors(
7435
7481
// stack as we descend through older versions, resetting once we hit a new
7436
7482
// key.
7437
7483
var nextRangeTombstone hlc.Timestamp
7438
- if isValue {
7439
- if ! rangeTombstones .IsEmpty () && unsafeKey .Timestamp .LessEq (rangeTombstones .Newest ()) {
7440
- if v , ok := rangeTombstones .FirstAtOrAbove (unsafeKey .Timestamp ); ok {
7441
- nextRangeTombstone = v .Timestamp
7442
- }
7484
+ if ! rangeTombstones .IsEmpty () && unsafeKey .Timestamp .LessEq (rangeTombstones .Newest ()) {
7485
+ if v , ok := rangeTombstones .FirstAtOrAbove (unsafeKey .Timestamp ); ok {
7486
+ nextRangeTombstone = v .Timestamp
7443
7487
}
7444
7488
}
7445
7489
7446
- var valueLen int
7447
- var mvccValueIsTombstone bool
7448
- if isValue {
7449
- // MVCC value
7450
- var err error
7451
- valueLen , mvccValueIsTombstone , err = iter .MVCCValueLenAndIsTombstone ()
7452
- if err != nil {
7453
- return enginepb.MVCCStats {}, errors .Wrap (err , "unable to decode MVCCValue" )
7454
- }
7455
- } else {
7456
- valueLen = iter .ValueLen ()
7490
+ valueLen , mvccValueIsTombstone , err := iter .MVCCValueLenAndIsTombstone ()
7491
+ if err != nil {
7492
+ return enginepb.MVCCStats {}, errors .Wrap (err , "unable to decode MVCCValue" )
7457
7493
}
7458
7494
if implicitMeta {
7459
7495
// INVARIANT: implicitMeta => isValue.
@@ -7463,34 +7499,21 @@ func computeStatsForIterWithVisitors(
7463
7499
meta .ValBytes = int64 (valueLen )
7464
7500
meta .Deleted = mvccValueIsTombstone
7465
7501
meta .Timestamp .WallTime = unsafeKey .Timestamp .WallTime
7466
- }
7467
7502
7468
- if ! isValue || implicitMeta {
7469
7503
metaKeySize := int64 (len (unsafeKey .Key )) + 1
7470
- var metaValSize int64
7471
- if ! implicitMeta {
7472
- metaValSize = int64 (valueLen )
7473
- }
7474
- totalBytes := metaKeySize + metaValSize
7504
+ totalBytes := metaKeySize
7475
7505
first = true
7476
7506
7477
7507
if isSys {
7478
7508
ms .SysBytes += totalBytes
7479
7509
ms .SysCount ++
7480
- if isAbortSpanKey (unsafeKey .Key ) {
7481
- ms .AbortSpanBytes += totalBytes
7510
+ // We don't need to account for the abort-span key here because
7511
+ // that key is not versioned.
7512
+ if buildutil .CrdbTestBuild && isAbortSpanKey (unsafeKey .Key ) {
7513
+ return enginepb.MVCCStats {}, errors .AssertionFailedf (
7514
+ "versioned abort span key encountered by ComputeStats: %s" , unsafeKey .Key )
7482
7515
}
7483
7516
} else {
7484
- if ! implicitMeta {
7485
- v , err := iter .UnsafeValue ()
7486
- if err != nil {
7487
- return enginepb.MVCCStats {}, err
7488
- }
7489
- if err := protoutil .Unmarshal (v , & meta ); err != nil {
7490
- return ms , errors .Wrap (err , "unable to decode MVCCMetadata" )
7491
- }
7492
- }
7493
-
7494
7517
if meta .Deleted {
7495
7518
// First value is deleted, so it's GC'able; add meta key & value bytes to age stat.
7496
7519
ms .GCBytesAge += totalBytes * (nowNanos / 1e9 - meta .Timestamp .WallTime / 1e9 )
@@ -7503,68 +7526,64 @@ func computeStatsForIterWithVisitors(
7503
7526
ms .LiveCount ++
7504
7527
}
7505
7528
ms .KeyBytes += metaKeySize
7506
- ms .ValBytes += metaValSize
7507
7529
ms .KeyCount ++
7508
7530
if meta .IsInline () {
7509
7531
ms .ValCount ++
7510
7532
}
7511
7533
}
7512
- if ! implicitMeta {
7513
- continue
7514
- }
7515
7534
}
7516
7535
7517
7536
totalBytes := int64 (valueLen ) + MVCCVersionTimestampSize
7518
7537
if isSys {
7519
7538
ms .SysBytes += totalBytes
7539
+ continue
7540
+ }
7541
+ ms .KeyBytes += MVCCVersionTimestampSize
7542
+ ms .ValBytes += int64 (valueLen )
7543
+ ms .ValCount ++
7544
+ if first {
7545
+ first = false
7546
+ if meta .Deleted {
7547
+ // First value is deleted, so it's GC'able; add key & value bytes to age stat.
7548
+ ms .GCBytesAge += totalBytes * (nowNanos / 1e9 - meta .Timestamp .WallTime / 1e9 )
7549
+ } else if nextRangeTombstone .IsSet () {
7550
+ // First value was deleted by a range tombstone; add key & value bytes to
7551
+ // age stat from range tombstone onwards.
7552
+ ms .GCBytesAge += totalBytes * (nowNanos / 1e9 - nextRangeTombstone .WallTime / 1e9 )
7553
+ } else {
7554
+ ms .LiveBytes += totalBytes
7555
+ }
7556
+ if meta .Txn != nil {
7557
+ ms .IntentBytes += totalBytes
7558
+ ms .IntentCount ++
7559
+ ms .LockCount ++
7560
+ ms .LockAge += nowNanos / 1e9 - meta .Timestamp .WallTime / 1e9
7561
+ }
7562
+ if meta .KeyBytes != MVCCVersionTimestampSize {
7563
+ return ms , errors .Errorf ("expected mvcc metadata key bytes to equal %d; got %d " +
7564
+ "(meta: %s)" , MVCCVersionTimestampSize , meta .KeyBytes , & meta )
7565
+ }
7566
+ if meta .ValBytes != int64 (valueLen ) {
7567
+ return ms , errors .Errorf ("expected mvcc metadata val bytes to equal %d; got %d " +
7568
+ "(meta: %s)" , valueLen , meta .ValBytes , & meta )
7569
+ }
7570
+ accrueGCAgeNanos = meta .Timestamp .WallTime
7520
7571
} else {
7521
- if first {
7522
- first = false
7523
- if meta .Deleted {
7524
- // First value is deleted, so it's GC'able; add key & value bytes to age stat.
7525
- ms .GCBytesAge += totalBytes * (nowNanos / 1e9 - meta .Timestamp .WallTime / 1e9 )
7526
- } else if nextRangeTombstone .IsSet () {
7527
- // First value was deleted by a range tombstone; add key & value bytes to
7528
- // age stat from range tombstone onwards.
7529
- ms .GCBytesAge += totalBytes * (nowNanos / 1e9 - nextRangeTombstone .WallTime / 1e9 )
7530
- } else {
7531
- ms .LiveBytes += totalBytes
7532
- }
7533
- if meta .Txn != nil {
7534
- ms .IntentBytes += totalBytes
7535
- ms .IntentCount ++
7536
- ms .LockCount ++
7537
- ms .LockAge += nowNanos / 1e9 - meta .Timestamp .WallTime / 1e9
7538
- }
7539
- if meta .KeyBytes != MVCCVersionTimestampSize {
7540
- return ms , errors .Errorf ("expected mvcc metadata key bytes to equal %d; got %d " +
7541
- "(meta: %s)" , MVCCVersionTimestampSize , meta .KeyBytes , & meta )
7542
- }
7543
- if meta .ValBytes != int64 (valueLen ) {
7544
- return ms , errors .Errorf ("expected mvcc metadata val bytes to equal %d; got %d " +
7545
- "(meta: %s)" , valueLen , meta .ValBytes , & meta )
7546
- }
7547
- accrueGCAgeNanos = meta .Timestamp .WallTime
7572
+ // Overwritten value. Is it a deletion tombstone?
7573
+ if mvccValueIsTombstone {
7574
+ // The contribution of the tombstone picks up GCByteAge from its own timestamp on.
7575
+ ms .GCBytesAge += totalBytes * (nowNanos / 1e9 - unsafeKey .Timestamp .WallTime / 1e9 )
7576
+ } else if nextRangeTombstone .IsSet () && nextRangeTombstone .WallTime < accrueGCAgeNanos {
7577
+ // The kv pair was deleted by a range tombstone below the next
7578
+ // version, so it accumulates garbage from the range tombstone.
7579
+ ms .GCBytesAge += totalBytes * (nowNanos / 1e9 - nextRangeTombstone .WallTime / 1e9 )
7548
7580
} else {
7549
- // Overwritten value. Is it a deletion tombstone?
7550
- if mvccValueIsTombstone {
7551
- // The contribution of the tombstone picks up GCByteAge from its own timestamp on.
7552
- ms .GCBytesAge += totalBytes * (nowNanos / 1e9 - unsafeKey .Timestamp .WallTime / 1e9 )
7553
- } else if nextRangeTombstone .IsSet () && nextRangeTombstone .WallTime < accrueGCAgeNanos {
7554
- // The kv pair was deleted by a range tombstone below the next
7555
- // version, so it accumulates garbage from the range tombstone.
7556
- ms .GCBytesAge += totalBytes * (nowNanos / 1e9 - nextRangeTombstone .WallTime / 1e9 )
7557
- } else {
7558
- // The kv pair is an overwritten value, so it became non-live when the closest more
7559
- // recent value was written.
7560
- ms .GCBytesAge += totalBytes * (nowNanos / 1e9 - accrueGCAgeNanos / 1e9 )
7561
- }
7562
- // Update for the next version we may end up looking at.
7563
- accrueGCAgeNanos = unsafeKey .Timestamp .WallTime
7581
+ // The kv pair is an overwritten value, so it became non-live when the closest more
7582
+ // recent value was written.
7583
+ ms .GCBytesAge += totalBytes * (nowNanos / 1e9 - accrueGCAgeNanos / 1e9 )
7564
7584
}
7565
- ms .KeyBytes += MVCCVersionTimestampSize
7566
- ms .ValBytes += int64 (valueLen )
7567
- ms .ValCount ++
7585
+ // Update for the next version we may end up looking at.
7586
+ accrueGCAgeNanos = unsafeKey .Timestamp .WallTime
7568
7587
}
7569
7588
}
7570
7589
0 commit comments