diff --git a/compaction_picker.go b/compaction_picker.go index 23239d0cf7..f9b54dc1aa 100644 --- a/compaction_picker.go +++ b/compaction_picker.go @@ -1239,8 +1239,13 @@ func (a elisionOnlyAnnotator) Accumulate(f *fileMetadata, dst interface{}) (inte // which may be collapsed. Ideally, we would have 'obsolete keys' // statistics that would include tombstones, the keys that are // dropped by tombstones and duplicated user keys. See #847. + // + // Note that tables that contain exclusively range keys (i.e. no point keys, + // `NumEntries` and `RangeDeletionsBytesEstimate` are both zero) are excluded + // from elision-only compactions. + // TODO(travers): Consider an alternative heuristic for elision of range-keys. if f.Stats.RangeDeletionsBytesEstimate*10 < f.Size && - f.Stats.NumDeletions*10 < f.Stats.NumEntries { + f.Stats.NumDeletions*10 <= f.Stats.NumEntries { return dst, true } if dst == nil { diff --git a/compaction_picker_test.go b/compaction_picker_test.go index 3f5dfa180c..4703e6380d 100644 --- a/compaction_picker_test.go +++ b/compaction_picker_test.go @@ -1176,6 +1176,7 @@ func TestCompactionOutputFileSize(t *testing.T) { } m.Stats.Valid = true m.Stats.RangeDeletionsBytesEstimate = uint64(v) + m.Stats.NumDeletions = 1 // At least one range del responsible for the deletion bytes. } } m.SmallestSeqNum = m.Smallest.SeqNum() diff --git a/compaction_test.go b/compaction_test.go index 6c73463303..f9eafb83a2 100644 --- a/compaction_test.go +++ b/compaction_test.go @@ -2097,6 +2097,7 @@ func TestCompactionTombstones(t *testing.T) { compactInfo = &info }, }, + FormatMajorVersion: FormatNewest, } var err error d, err = runDBDefineCmd(td, opts) diff --git a/testdata/compaction_tombstones b/testdata/compaction_tombstones index b1cd72482d..5151eb9dc9 100644 --- a/testdata/compaction_tombstones +++ b/testdata/compaction_tombstones @@ -244,3 +244,50 @@ range-deletions-bytes-estimate: 0 maybe-compact ---- [JOB 100] compacted(default) L5 [000004] (794 B) + L6 [000006] (13 K) -> L6 [] (0 B), in 1.0s (2.0s total), output rate 0 B/s + +# A table containing only range keys is not eligible for elision. +# RANGEKEYDEL or RANGEKEYUNSET. + +define +L6 + rangekey:a-b:{(#1,RANGEKEYDEL)} +L6 + rangekey:b-c:{(#2,RANGEKEYUNSET,@1)} +L6 + rangekey:c-d:{(#3,RANGEKEYSET,@1)} +---- +6: + 000004:[a#1,RANGEKEYDEL-b#72057594037927935,RANGEKEYDEL] + 000005:[b#2,RANGEKEYUNSET-c#72057594037927935,RANGEKEYUNSET] + 000006:[c#3,RANGEKEYSET-d#72057594037927935,RANGEKEYSET] + +wait-pending-table-stats +000004 +---- +num-entries: 0 +num-deletions: 0 +num-range-keys: 1 +point-deletions-bytes-estimate: 0 +range-deletions-bytes-estimate: 0 + +wait-pending-table-stats +000005 +---- +num-entries: 0 +num-deletions: 0 +num-range-keys: 1 +point-deletions-bytes-estimate: 0 +range-deletions-bytes-estimate: 0 + +wait-pending-table-stats +000006 +---- +num-entries: 0 +num-deletions: 0 +num-range-keys: 1 +point-deletions-bytes-estimate: 0 +range-deletions-bytes-estimate: 0 + +maybe-compact +---- +(none)