@@ -1960,7 +1960,7 @@ type ParseHooks struct {
19601960 NewFilterPolicy func (name string ) (FilterPolicy , error )
19611961 NewKeySchema func (name string ) (KeySchema , error )
19621962 NewMerger func (name string ) (* Merger , error )
1963- SkipUnknown func (name , value string ) bool
1963+ OnUnknown func (name , value string )
19641964}
19651965
19661966// Parse parses the options from the specified string. Note that certain
@@ -1976,11 +1976,6 @@ func (o *Options) Parse(s string, hooks *ParseHooks) error {
19761976 }
19771977
19781978 visitKeyValue := func (i , j int , section , key , value string ) error {
1979- // WARNING: DO NOT remove entries from the switches below because doing so
1980- // causes a key previously written to the OPTIONS file to be considered unknown,
1981- // a backwards incompatible change. Instead, leave in support for parsing the
1982- // key but simply don't parse the value.
1983-
19841979 parseComparer := func (name string ) (* Comparer , error ) {
19851980 switch name {
19861981 case DefaultComparer .Name :
@@ -2000,11 +1995,15 @@ func (o *Options) Parse(s string, hooks *ParseHooks) error {
20001995 switch key {
20011996 case "pebble_version" :
20021997 default :
2003- if hooks != nil && hooks .SkipUnknown != nil && hooks .SkipUnknown (section + "." + key , value ) {
1998+ if hooks != nil && hooks .OnUnknown != nil {
1999+ hooks .OnUnknown (section + "." + key , value )
20042000 return nil
20052001 }
2006- return errors .Errorf ("pebble: unknown option: %s.%s" ,
2007- errors .Safe (section ), errors .Safe (key ))
2002+ // Tolerate unknown options, but log them.
2003+ if o .Logger != nil {
2004+ o .Logger .Infof ("pebble: unknown option: %s.%s" , errors .Safe (section ), errors .Safe (key ))
2005+ }
2006+ return nil
20082007 }
20092008 return nil
20102009
@@ -2059,8 +2058,6 @@ func (o *Options) Parse(s string, hooks *ParseHooks) error {
20592058 o .private .disableLazyCombinedIteration , err = strconv .ParseBool (value )
20602059 case "disable_wal" :
20612060 o .DisableWAL , err = strconv .ParseBool (value )
2062- case "enable_columnar_blocks" :
2063- // Do nothing; option existed in older versions of pebble.
20642061 case "flush_delay_delete_range" :
20652062 o .FlushDelayDeleteRange , err = time .ParseDuration (value )
20662063 case "flush_delay_range_key" :
@@ -2074,7 +2071,18 @@ func (o *Options) Parse(s string, hooks *ParseHooks) error {
20742071 // version is valid right here.
20752072 var v uint64
20762073 v , err = strconv .ParseUint (value , 10 , 64 )
2077- if vers := FormatMajorVersion (v ); vers > internalFormatNewest || vers == FormatDefault {
2074+ vers := FormatMajorVersion (v )
2075+ if vers > internalFormatNewest {
2076+ // Tolerate new unknown format versions in OPTIONS file (they
2077+ // may be stale if a format upgrade was reverted before
2078+ // finalization). The actual format version is determined by
2079+ // the format version marker file.
2080+ if o .Logger != nil {
2081+ o .Logger .Infof (
2082+ "pebble: format major version %d in OPTIONS file is newer than supported (%d), ignoring" ,
2083+ vers , internalFormatNewest )
2084+ }
2085+ } else if vers == FormatDefault {
20782086 err = errors .Newf ("unsupported format major version %d" , o .FormatMajorVersion )
20792087 }
20802088 if err == nil {
@@ -2118,8 +2126,6 @@ func (o *Options) Parse(s string, hooks *ParseHooks) error {
21182126 o .L0CompactionThreshold , err = strconv .Atoi (value )
21192127 case "l0_stop_writes_threshold" :
21202128 o .L0StopWritesThreshold , err = strconv .Atoi (value )
2121- case "l0_sublevel_compactions" :
2122- // Do nothing; option existed in older versions of pebble.
21232129 case "lbase_max_bytes" :
21242130 o .LBaseMaxBytes , err = strconv .ParseInt (value , 10 , 64 )
21252131 case "level_multiplier" :
@@ -2146,9 +2152,6 @@ func (o *Options) Parse(s string, hooks *ParseHooks) error {
21462152 o .MemTableSize , err = strconv .ParseUint (value , 10 , 64 )
21472153 case "mem_table_stop_writes_threshold" :
21482154 o .MemTableStopWritesThreshold , err = strconv .Atoi (value )
2149- case "min_compaction_rate" :
2150- // Do nothing; option existed in older versions of pebble, and
2151- // may be meaningful again eventually.
21522155 case "min_deletion_rate" :
21532156 var rate uint64
21542157 rate , err = strconv .ParseUint (value , 10 , 64 )
@@ -2159,13 +2162,8 @@ func (o *Options) Parse(s string, hooks *ParseHooks) error {
21592162 o .DeletionPacing .FreeSpaceThresholdBytes , err = strconv .ParseUint (value , 10 , 64 )
21602163 case "free_space_timeframe" :
21612164 o .DeletionPacing .FreeSpaceTimeframe , err = time .ParseDuration (value )
2162- case "obsolete_bytes_max_ratio" :
2163- // No longer used.
21642165 case "obsolete_bytes_timeframe" :
21652166 o .DeletionPacing .BacklogTimeframe , err = time .ParseDuration (value )
2166- case "min_flush_rate" :
2167- // Do nothing; option existed in older versions of pebble, and
2168- // may be meaningful again eventually.
21692167 case "multilevel_compaction_heuristic" :
21702168 switch {
21712169 case value == "none" :
@@ -2196,10 +2194,11 @@ func (o *Options) Parse(s string, hooks *ParseHooks) error {
21962194 err = errors .Wrapf (err , "unexpected wamp heuristic arguments: %s" , value )
21972195 }
21982196 default :
2199- err = errors .Newf ("unrecognized multilevel compaction heuristic: %s" , value )
2197+ // Tolerate unknown options, but log them.
2198+ if o .Logger != nil {
2199+ o .Logger .Infof ("pebble: unrecognized multilevel compaction heuristic: %s" , value )
2200+ }
22002201 }
2201- case "point_tombstone_weight" :
2202- // Do nothing; deprecated.
22032202 case "strict_wal_tail" :
22042203 var strictWALTail bool
22052204 strictWALTail , err = strconv .ParseBool (value )
@@ -2240,20 +2239,18 @@ func (o *Options) Parse(s string, hooks *ParseHooks) error {
22402239 case "leveldb" :
22412240 case "rocksdbv2" :
22422241 default :
2243- return errors .Errorf ("pebble: unknown table format: %q" , errors .Safe (value ))
2242+ // Tolerate unknown options, but log them.
2243+ if o .Logger != nil {
2244+ o .Logger .Infof ("pebble: unknown table format: %q" , errors .Safe (value ))
2245+ }
2246+ return nil
22442247 }
2245- case "table_property_collectors" :
2246- // No longer implemented; ignore.
22472248 case "validate_on_ingest" :
22482249 o .Experimental .ValidateOnIngest , err = strconv .ParseBool (value )
22492250 case "wal_dir" :
22502251 o .WALDir = value
22512252 case "wal_bytes_per_sync" :
22522253 o .WALBytesPerSync , err = strconv .Atoi (value )
2253- case "max_writer_concurrency" :
2254- // No longer implemented; ignore.
2255- case "force_writer_parallelism" :
2256- // No longer implemented; ignore.
22572254 case "secondary_cache_size_bytes" :
22582255 o .Experimental .SecondaryCacheSizeBytes , err = strconv .ParseInt (value , 10 , 64 )
22592256 case "create_on_shared" :
@@ -2265,11 +2262,15 @@ func (o *Options) Parse(s string, hooks *ParseHooks) error {
22652262 case "iterator_tracking_max_age" :
22662263 o .Experimental .IteratorTracking .MaxAge , err = time .ParseDuration (value )
22672264 default :
2268- if hooks != nil && hooks .SkipUnknown != nil && hooks .SkipUnknown (section + "." + key , value ) {
2265+ if hooks != nil && hooks .OnUnknown != nil {
2266+ hooks .OnUnknown (section + "." + key , value )
22692267 return nil
22702268 }
2271- return errors .Errorf ("pebble: unknown option: %s.%s" ,
2272- errors .Safe (section ), errors .Safe (key ))
2269+ // Tolerate unknown options, but log them.
2270+ if o .Logger != nil {
2271+ o .Logger .Infof ("pebble: unknown option: %s.%s" , errors .Safe (section ), errors .Safe (key ))
2272+ }
2273+ return nil
22732274 }
22742275 return err
22752276
@@ -2292,10 +2293,15 @@ func (o *Options) Parse(s string, hooks *ParseHooks) error {
22922293 case "garbage_ratio_high_priority" :
22932294 valSepPolicy .GarbageRatioHighPriority , err = strconv .ParseFloat (value , 64 )
22942295 default :
2295- if hooks != nil && hooks .SkipUnknown != nil && hooks .SkipUnknown (section + "." + key , value ) {
2296+ if hooks != nil && hooks .OnUnknown != nil {
2297+ hooks .OnUnknown (section + "." + key , value )
22962298 return nil
22972299 }
2298- return errors .Errorf ("pebble: unknown option: %s.%s" , errors .Safe (section ), errors .Safe (key ))
2300+ // Tolerate unknown options, but log them.
2301+ if o .Logger != nil {
2302+ o .Logger .Infof ("pebble: unknown option: %s.%s" , errors .Safe (section ), errors .Safe (key ))
2303+ }
2304+ return nil
22992305 }
23002306 return err
23012307
@@ -2324,11 +2330,15 @@ func (o *Options) Parse(s string, hooks *ParseHooks) error {
23242330 case "elevated_write_stall_threshold_lag" :
23252331 o .WALFailover .ElevatedWriteStallThresholdLag , err = time .ParseDuration (value )
23262332 default :
2327- if hooks != nil && hooks .SkipUnknown != nil && hooks .SkipUnknown (section + "." + key , value ) {
2333+ if hooks != nil && hooks .OnUnknown != nil {
2334+ hooks .OnUnknown (section + "." + key , value )
23282335 return nil
23292336 }
2330- return errors .Errorf ("pebble: unknown option: %s.%s" ,
2331- errors .Safe (section ), errors .Safe (key ))
2337+ // Tolerate unknown options, but log them.
2338+ if o .Logger != nil {
2339+ o .Logger .Infof ("pebble: unknown option: %s.%s" , errors .Safe (section ), errors .Safe (key ))
2340+ }
2341+ return nil
23322342 }
23332343 return err
23342344
@@ -2368,24 +2378,38 @@ func (o *Options) Parse(s string, hooks *ParseHooks) error {
23682378 case "table" :
23692379 l .FilterType = TableFilter
23702380 default :
2371- return errors .Errorf ("pebble: unknown filter type: %q" , errors .Safe (value ))
2381+ // Tolerate unknown options, but log them.
2382+ if o .Logger != nil {
2383+ o .Logger .Infof ("pebble: unknown filter type: %q" , errors .Safe (value ))
2384+ }
2385+ return nil
23722386 }
23732387 case "index_block_size" :
23742388 l .IndexBlockSize , err = strconv .Atoi (value )
23752389 case "target_file_size" :
23762390 o .TargetFileSizes [index ], err = strconv .ParseInt (value , 10 , 64 )
23772391 default :
2378- if hooks != nil && hooks .SkipUnknown != nil && hooks .SkipUnknown (section + "." + key , value ) {
2392+ if hooks != nil && hooks .OnUnknown != nil {
2393+ hooks .OnUnknown (section + "." + key , value )
23792394 return nil
23802395 }
2381- return errors .Errorf ("pebble: unknown option: %s.%s" , errors .Safe (section ), errors .Safe (key ))
2396+ // Tolerate unknown options, but log them.
2397+ if o .Logger != nil {
2398+ o .Logger .Infof ("pebble: unknown option: %s.%s" , errors .Safe (section ), errors .Safe (key ))
2399+ }
2400+ return nil
23822401 }
23832402 return err
23842403 }
2385- if hooks != nil && hooks .SkipUnknown != nil && hooks .SkipUnknown (section + "." + key , value ) {
2404+ if hooks != nil && hooks .OnUnknown != nil {
2405+ hooks .OnUnknown (section + "." + key , value )
23862406 return nil
23872407 }
2388- return errors .Errorf ("pebble: unknown section %q or key %q" , errors .Safe (section ), errors .Safe (key ))
2408+ // Tolerate unknown sections and keys, but log them.
2409+ if o .Logger != nil {
2410+ o .Logger .Infof ("pebble: unknown section %q or key %q" , errors .Safe (section ), errors .Safe (key ))
2411+ }
2412+ return nil
23892413 }
23902414 err := parseOptions (s , parseOptionsFuncs {
23912415 visitKeyValue : visitKeyValue ,
0 commit comments