Skip to content

Commit eda4c4a

Browse files
committed
sstable: in props, remove ValueSeparationKind, add ValueSeparationBySuffixDisabled
Remove ValueSeparationKind, which was originally added for compaction decisions but was not necessary in the end. Add the property ValueSeparationBySuffixDisabled, which indicates if the table used special value separation policies for mvcc garbage to inform value separation decisions during compactions.
1 parent a3b6a96 commit eda4c4a

32 files changed

+515
-519
lines changed

compaction_value_separation.go

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -123,31 +123,39 @@ func shouldWriteBlobFiles(
123123
continue
124124
}
125125

126-
var expectedMinSize int
126+
// Set expected policy to global policy values to start, and
127+
// extract the expected values from the span policy.
128+
expectedMinSize := policy.MinimumSize
129+
expectedValSepBySuffixDisabled := false
127130
bounds := t.UserKeyBounds()
128131
spanPolicy, spanPolicyEndKey, err := spanPolicyFunc(bounds.Start)
129-
if err != nil {
130-
// For now, if we can't determine the span policy, we should just assume
131-
// the default policy is in effect for this table.
132-
expectedMinSize = policy.MinimumSize
133-
} else {
132+
// For now, if we can't determine the span policy, we should just assume
133+
// the default policy is in effect for this table.
134+
if err == nil {
134135
if len(spanPolicyEndKey) > 0 && cmp(bounds.End.Key, spanPolicyEndKey) >= 0 {
135136
// The table's key range now uses multiple span policies. Rewrite to new
136137
// blob files so values are stored according to the current policy.
137138
return true, 0
138139
}
139140
switch spanPolicy.ValueStoragePolicy.PolicyAdjustment {
140141
case UseDefaultValueStorage:
141-
// Use the global policy's minimum size.
142-
expectedMinSize = policy.MinimumSize
142+
// Use the global policy.
143143
case OverrideValueStorage:
144144
expectedMinSize = spanPolicy.ValueStoragePolicy.MinimumSize
145+
if expectedMinSize == 0 {
146+
// A 0 minimum value size on the span policy indicates the field
147+
// was unset, but other parts of value separation are being
148+
// overridden. Use the default min size.
149+
expectedMinSize = policy.MinimumSize
150+
}
151+
expectedValSepBySuffixDisabled = spanPolicy.ValueStoragePolicy.DisableSeparationBySuffix
145152
case NoValueSeparation:
146153
expectedMinSize = 0
147154
}
148155
}
149156

150-
if int(backingProps.ValueSeparationMinSize) != expectedMinSize {
157+
if int(backingProps.ValueSeparationMinSize) != expectedMinSize ||
158+
(expectedMinSize > 0 && backingProps.ValueSeparationBySuffixDisabled != expectedValSepBySuffixDisabled) {
151159
return true, 0
152160
}
153161
}

data_test.go

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1939,14 +1939,11 @@ var _ valsep.ValueSeparation = (*defineDBValueSeparator)(nil)
19391939
// SetNextOutputConfig implements the valsep.ValueSeparation interface.
19401940
func (vs *defineDBValueSeparator) SetNextOutputConfig(config valsep.ValueSeparationOutputConfig) {}
19411941

1942-
// Kind implements the ValueSeparation interface.
1943-
func (vs *defineDBValueSeparator) Kind() sstable.ValueSeparationKind {
1944-
return vs.pbr.Kind()
1942+
// OutputConfig implements the valsep.ValueSeparation interface.
1943+
func (vs *defineDBValueSeparator) OutputConfig() valsep.ValueSeparationOutputConfig {
1944+
return vs.pbr.OutputConfig()
19451945
}
19461946

1947-
// MinimumSize implements the ValueSeparation interface.
1948-
func (vs *defineDBValueSeparator) MinimumSize() int { return vs.pbr.MinimumSize() }
1949-
19501947
// EstimatedFileSize returns an estimate of the disk space consumed by the current
19511948
// blob file if it were closed now.
19521949
func (vs *defineDBValueSeparator) EstimatedFileSize() uint64 {

internal/compact/run.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,8 +190,9 @@ func (r *Runner) WriteTable(
190190
panic("error already encountered")
191191
}
192192

193-
// Set the value separation kind on the writer based on the strategy being used.
194-
tw.SetValueSeparationProps(valueSeparation.Kind(), uint64(valueSeparation.MinimumSize()))
193+
// Set the value separation props on the writer.
194+
config := valueSeparation.OutputConfig()
195+
tw.SetValueSeparationProps(uint64(config.MinimumSize), config.DisableValueSeparationBySuffix)
195196

196197
r.tables = append(r.tables, OutputTable{
197198
CreationTime: time.Now(),

internal/manifest/table_metadata.go

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -414,12 +414,14 @@ type TableBackingProperties struct {
414414

415415
CompressionStats block.CompressionStats
416416

417-
// ValueSeparationKind is the value separation policy used when writing the table.
418-
ValueSeparationKind sstable.ValueSeparationKind
419417
// ValueSeparationMinSize is the minimum value size for which values were
420418
// separated when writing the table. This value is 0 if the policy used
421419
// does not write blob files.
422420
ValueSeparationMinSize uint64
421+
// ValueSeparationBySuffixDisabled indicates if disabled applying special
422+
// value separation rules by KV suffix when writing the table. Note that
423+
// if value separation was disabled, this field is not meaningful.
424+
ValueSeparationBySuffixDisabled bool
423425
}
424426

425427
// NumPointDeletions is the number of point deletions in the sstable. For virtual
@@ -443,19 +445,19 @@ func (b *TableBacking) Properties() (_ *TableBackingProperties, ok bool) {
443445
// TableBacking.
444446
func (b *TableBacking) PopulateProperties(props *sstable.Properties) *TableBackingProperties {
445447
b.props = TableBackingProperties{
446-
NumEntries: props.NumEntries,
447-
RawKeySize: props.RawKeySize,
448-
RawValueSize: props.RawValueSize,
449-
RawPointTombstoneKeySize: props.RawPointTombstoneKeySize,
450-
RawPointTombstoneValueSize: props.RawPointTombstoneValueSize,
451-
NumSizedDeletions: props.NumSizedDeletions,
452-
NumDeletions: props.NumDeletions,
453-
NumRangeDeletions: props.NumRangeDeletions,
454-
NumRangeKeyDels: props.NumRangeKeyDels,
455-
NumRangeKeySets: props.NumRangeKeySets,
456-
ValueBlocksSize: props.ValueBlocksSize,
457-
ValueSeparationKind: sstable.ValueSeparationKind(props.ValueSeparationKind),
458-
ValueSeparationMinSize: props.ValueSeparationMinSize,
448+
NumEntries: props.NumEntries,
449+
RawKeySize: props.RawKeySize,
450+
RawValueSize: props.RawValueSize,
451+
RawPointTombstoneKeySize: props.RawPointTombstoneKeySize,
452+
RawPointTombstoneValueSize: props.RawPointTombstoneValueSize,
453+
NumSizedDeletions: props.NumSizedDeletions,
454+
NumDeletions: props.NumDeletions,
455+
NumRangeDeletions: props.NumRangeDeletions,
456+
NumRangeKeyDels: props.NumRangeKeyDels,
457+
NumRangeKeySets: props.NumRangeKeySets,
458+
ValueBlocksSize: props.ValueBlocksSize,
459+
ValueSeparationMinSize: props.ValueSeparationMinSize,
460+
ValueSeparationBySuffixDisabled: props.ValueSeparationBySuffixDisabled,
459461
}
460462
if props.NumDataBlocks != 0 {
461463
b.props.TombstoneDenseBlocksRatio = float64(props.NumTombstoneDenseBlocks) / float64(props.NumDataBlocks)

options.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1322,10 +1322,6 @@ type ValueStoragePolicyAdjustment struct {
13221322
// optimize access to the KV with the smallest suffix. This is useful for MVCC
13231323
// keys (where the smallest suffix is the latest version), but should be
13241324
// disabled for keys where the suffix does not correspond to a version.
1325-
//
1326-
// TODO(xinhaoz): Persist this setting when writing sstables so we can
1327-
// compare against current span policy configs during compaction to determine
1328-
// whether we can preserve blob references.
13291325
DisableSeparationBySuffix bool
13301326
// MinimumSize is the minimum size of the value.
13311327
MinimumSize int

replay/testdata/corpus/simple_val_sep

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,6 @@ stat simple_val_sep/MANIFEST-000013 simple_val_sep/000015.sst simple_val_sep/000
103103
simple_val_sep/MANIFEST-000013:
104104
size: 250
105105
simple_val_sep/000015.sst:
106-
size: 802
106+
size: 792
107107
simple_val_sep/000016.blob:
108108
size: 97

replay/testdata/replay_val_sep

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ tree
55
----
66
/
77
build/
8-
829 000005.sst
8+
819 000005.sst
99
101 000006.blob
10-
808 000008.sst
10+
798 000008.sst
1111
97 000009.blob
1212
92 000011.log
13-
707 000012.sst
13+
687 000012.sst
1414
63 000014.log
15-
802 000015.sst
15+
792 000015.sst
1616
97 000016.blob
1717
0 LOCK
1818
152 MANIFEST-000010
@@ -21,16 +21,16 @@ tree
2121
0 marker.format-version.000011.024
2222
0 marker.manifest.000003.MANIFEST-000013
2323
simple_val_sep/
24-
802 000015.sst
24+
792 000015.sst
2525
97 000016.blob
2626
250 MANIFEST-000013
2727
checkpoint/
28-
829 000005.sst
28+
819 000005.sst
2929
101 000006.blob
30-
808 000008.sst
30+
798 000008.sst
3131
97 000009.blob
3232
11 000011.log
33-
707 000012.sst
33+
687 000012.sst
3434
187 MANIFEST-000013
3535
2911 OPTIONS-000002
3636
0 marker.format-version.000001.024

sstable/colblk_writer.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1273,9 +1273,11 @@ func (w *RawColumnWriter) copyProperties(props Properties) {
12731273
}
12741274

12751275
// SetValueSeparationProps implements RawWriter.
1276-
func (w *RawColumnWriter) SetValueSeparationProps(kind ValueSeparationKind, minValueSize uint64) {
1277-
w.props.ValueSeparationKind = uint8(kind)
1276+
func (w *RawColumnWriter) SetValueSeparationProps(
1277+
minValueSize uint64, disableSeparationBySuffix bool,
1278+
) {
12781279
w.props.ValueSeparationMinSize = minValueSize
1280+
w.props.ValueSeparationBySuffixDisabled = disableSeparationBySuffix
12791281
}
12801282

12811283
// IsLikelyMVCCGarbage determines whether the given user key is likely MVCC

sstable/properties.go

Lines changed: 4 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -122,13 +122,12 @@ type Properties struct {
122122
// The compression statistics encoded as a string. The format is:
123123
// "<setting1>:<compressed1>/<uncompressed1>,<setting2>:<compressed2>/<uncompressed2>,..."
124124
CompressionStats string `prop:"pebble.compression_stats"`
125-
// The value separation policy that was used when writing this sstable.
126-
// This indicates how values were handled during writing (separated into
127-
// blob files, preserved references, or kept in-place). See ValueSeparationKind type
128-
// for possible values.
129-
ValueSeparationKind uint8 `prop:"pebble.value-separation.kind"`
130125
// The minimum size a value must be to be separated into a blob file during writing.
131126
ValueSeparationMinSize uint64 `prop:"pebble.value-separation.min-size"`
127+
// ValueSeparationBySuffixDisabled indicates if special value separation rules were
128+
// applied based on the KV suffix when writing. Pebble attempts to optimize writing of
129+
// MVCC garbage values into blob files, which are recognized by the key suffix.
130+
ValueSeparationBySuffixDisabled bool `prop:"pebble.value-separation.by-suffix.disabled"`
132131
// User collected properties. Currently, we only use them to store block
133132
// properties aggregated at the table level.
134133
UserProperties map[string]string
@@ -231,25 +230,6 @@ func (p *Properties) toAttributes() Attributes {
231230
return attributes
232231
}
233232

234-
// ValueSeparationKind indicates the value separation policy that was used
235-
// when writing an sstable.
236-
type ValueSeparationKind uint8
237-
238-
const (
239-
// ValueSeparationNone indicates that no value separation was used.
240-
// All values are stored in-place within the sstable.
241-
ValueSeparationNone ValueSeparationKind = iota
242-
243-
// ValueSeparationDefault indicates that values were separated into
244-
// new blob files during writing using the default value separation
245-
// policy settings for minimum sizes.
246-
ValueSeparationDefault
247-
248-
// ValueSeparationSpanPolicy indicates that values were separated
249-
// based on a span policy during writing.
250-
ValueSeparationSpanPolicy
251-
)
252-
253233
var (
254234
singleZeroSlice = []byte{0x00}
255235
maxInt32Slice = binary.AppendUvarint([]byte(nil), math.MaxInt32)

sstable/properties_gen.go

Lines changed: 54 additions & 51 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)