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