8
8
"context"
9
9
"fmt"
10
10
"math"
11
+ "time"
11
12
13
+ "github.com/cockroachdb/crlib/crtime"
12
14
"github.com/cockroachdb/errors"
13
15
"github.com/cockroachdb/pebble/internal/base"
14
16
"github.com/cockroachdb/pebble/internal/invariants"
@@ -17,6 +19,7 @@ import (
17
19
"github.com/cockroachdb/pebble/internal/manifest"
18
20
"github.com/cockroachdb/pebble/sstable"
19
21
"github.com/cockroachdb/pebble/sstable/block"
22
+ "github.com/cockroachdb/redact"
20
23
)
21
24
22
25
// In-memory statistics about tables help inform compaction picking, but may
@@ -131,6 +134,7 @@ func (d *DB) collectTableStats() bool {
131
134
for _ , c := range collected {
132
135
c .tableMetadata .Stats = c .TableStats
133
136
maybeCompact = maybeCompact || fileCompensation (c .tableMetadata ) > 0
137
+ sanityCheckStats (c .tableMetadata , d .opts .Logger , "collected stats" )
134
138
c .tableMetadata .StatsMarkValid ()
135
139
}
136
140
@@ -653,7 +657,29 @@ func (d *DB) estimateReclaimedSizeBeneath(
653
657
return estimate , hintSeqNum , nil
654
658
}
655
659
656
- func maybeSetStatsFromProperties (meta * tableMetadata , props * sstable.CommonProperties ) bool {
660
+ var lastSanityCheckStatsLog crtime.AtomicMono
661
+
662
+ func sanityCheckStats (meta * tableMetadata , logger Logger , info string ) {
663
+ // Values for PointDeletionsBytesEstimate and RangeDeletionsBytesEstimate that
664
+ // exceed this value are most likely indicative of a bug.
665
+ const maxDeletionBytesEstimate = 16 << 30 // 16 GiB
666
+
667
+ if meta .Stats .PointDeletionsBytesEstimate > maxDeletionBytesEstimate ||
668
+ meta .Stats .RangeDeletionsBytesEstimate > maxDeletionBytesEstimate {
669
+ if v := lastSanityCheckStatsLog .Load (); v == 0 || v .Elapsed () > 30 * time .Second {
670
+ logger .Errorf ("%s: table %s has extreme deletion bytes estimates: point=%d range=%d" ,
671
+ info , meta .FileNum ,
672
+ redact .Safe (meta .Stats .PointDeletionsBytesEstimate ),
673
+ redact .Safe (meta .Stats .RangeDeletionsBytesEstimate ),
674
+ )
675
+ lastSanityCheckStatsLog .Store (crtime .NowMono ())
676
+ }
677
+ }
678
+ }
679
+
680
+ func maybeSetStatsFromProperties (
681
+ meta * tableMetadata , props * sstable.CommonProperties , logger Logger ,
682
+ ) bool {
657
683
// If a table contains range deletions or range key deletions, we defer the
658
684
// stats collection. There are two main reasons for this:
659
685
//
@@ -697,6 +723,7 @@ func maybeSetStatsFromProperties(meta *tableMetadata, props *sstable.CommonPrope
697
723
meta .Stats .ValueBlocksSize = props .ValueBlocksSize
698
724
meta .Stats .CompressionType = block .CompressionFromString (props .CompressionName )
699
725
meta .StatsMarkValid ()
726
+ sanityCheckStats (meta , logger , "stats from properties" )
700
727
return true
701
728
}
702
729
0 commit comments