github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/storage/temp_engine.go (about)

     1  // Copyright 2017 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  package storage
    12  
    13  import (
    14  	"context"
    15  	"fmt"
    16  
    17  	"github.com/cockroachdb/cockroach/pkg/base"
    18  	"github.com/cockroachdb/cockroach/pkg/kv/kvserver/diskmap"
    19  	"github.com/cockroachdb/cockroach/pkg/roachpb"
    20  	"github.com/cockroachdb/cockroach/pkg/storage/enginepb"
    21  	"github.com/cockroachdb/cockroach/pkg/storage/fs"
    22  	"github.com/cockroachdb/cockroach/pkg/util/log"
    23  	"github.com/cockroachdb/pebble"
    24  	"github.com/cockroachdb/pebble/vfs"
    25  )
    26  
    27  // NewTempEngine creates a new engine for DistSQL processors to use when
    28  // the working set is larger than can be stored in memory.
    29  func NewTempEngine(
    30  	ctx context.Context,
    31  	engine enginepb.EngineType,
    32  	tempStorage base.TempStorageConfig,
    33  	storeSpec base.StoreSpec,
    34  ) (diskmap.Factory, fs.FS, error) {
    35  	switch engine {
    36  	case enginepb.EngineTypeTeePebbleRocksDB:
    37  		fallthrough
    38  	case enginepb.EngineTypeDefault, enginepb.EngineTypePebble:
    39  		return NewPebbleTempEngine(ctx, tempStorage, storeSpec)
    40  	case enginepb.EngineTypeRocksDB:
    41  		return NewRocksDBTempEngine(tempStorage, storeSpec)
    42  	}
    43  	panic(fmt.Sprintf("unknown engine type: %d", engine))
    44  }
    45  
    46  type rocksDBTempEngine struct {
    47  	db *RocksDB
    48  }
    49  
    50  // Close implements the diskmap.Factory interface.
    51  func (r *rocksDBTempEngine) Close() {
    52  	r.db.Close()
    53  }
    54  
    55  // NewSortedDiskMap implements the diskmap.Factory interface.
    56  func (r *rocksDBTempEngine) NewSortedDiskMap() diskmap.SortedDiskMap {
    57  	return newRocksDBMap(r.db, false /* allowDuplications */)
    58  }
    59  
    60  // NewSortedDiskMultiMap implements the diskmap.Factory interface.
    61  func (r *rocksDBTempEngine) NewSortedDiskMultiMap() diskmap.SortedDiskMap {
    62  	return newRocksDBMap(r.db, true /* allowDuplicates */)
    63  }
    64  
    65  // storageConfigFromTempStorageConfigAndStoreSpec creates a base.StorageConfig
    66  // used by both the RocksDB and Pebble temp engines from the given arguments.
    67  func storageConfigFromTempStorageConfigAndStoreSpec(
    68  	config base.TempStorageConfig, spec base.StoreSpec,
    69  ) base.StorageConfig {
    70  	return base.StorageConfig{
    71  		Attrs: roachpb.Attributes{},
    72  		Dir:   config.Path,
    73  		// MaxSize doesn't matter for temp storage - it's not enforced in any way.
    74  		MaxSize:         0,
    75  		UseFileRegistry: spec.UseFileRegistry,
    76  		ExtraOptions:    spec.ExtraOptions,
    77  	}
    78  }
    79  
    80  // NewRocksDBTempEngine creates a new RocksDB engine for DistSQL processors to use when
    81  // the working set is larger than can be stored in memory.
    82  func NewRocksDBTempEngine(
    83  	tempStorage base.TempStorageConfig, storeSpec base.StoreSpec,
    84  ) (diskmap.Factory, fs.FS, error) {
    85  	if tempStorage.InMemory {
    86  		// TODO(arjun): Limit the size of the store once #16750 is addressed.
    87  		// Technically we do not pass any attributes to temporary store.
    88  		db := newRocksDBInMem(roachpb.Attributes{} /* attrs */, 0 /* cacheSize */)
    89  		return &rocksDBTempEngine{db: db}, db, nil
    90  	}
    91  
    92  	cfg := RocksDBConfig{
    93  		StorageConfig: storageConfigFromTempStorageConfigAndStoreSpec(tempStorage, storeSpec),
    94  		MaxOpenFiles:  128, // TODO(arjun): Revisit this.
    95  	}
    96  	rocksDBCache := NewRocksDBCache(0)
    97  	defer rocksDBCache.Release()
    98  	db, err := NewRocksDB(cfg, rocksDBCache)
    99  	if err != nil {
   100  		return nil, nil, err
   101  	}
   102  
   103  	return &rocksDBTempEngine{db: db}, db, nil
   104  }
   105  
   106  type pebbleTempEngine struct {
   107  	db *pebble.DB
   108  }
   109  
   110  // Close implements the diskmap.Factory interface.
   111  func (r *pebbleTempEngine) Close() {
   112  	err := r.db.Close()
   113  	if err != nil {
   114  		log.Fatalf(context.TODO(), "%v", err)
   115  	}
   116  }
   117  
   118  // NewSortedDiskMap implements the diskmap.Factory interface.
   119  func (r *pebbleTempEngine) NewSortedDiskMap() diskmap.SortedDiskMap {
   120  	return newPebbleMap(r.db, false /* allowDuplications */)
   121  }
   122  
   123  // NewSortedDiskMultiMap implements the diskmap.Factory interface.
   124  func (r *pebbleTempEngine) NewSortedDiskMultiMap() diskmap.SortedDiskMap {
   125  	return newPebbleMap(r.db, true /* allowDuplicates */)
   126  }
   127  
   128  // NewPebbleTempEngine creates a new Pebble engine for DistSQL processors to use
   129  // when the working set is larger than can be stored in memory.
   130  func NewPebbleTempEngine(
   131  	ctx context.Context, tempStorage base.TempStorageConfig, storeSpec base.StoreSpec,
   132  ) (diskmap.Factory, fs.FS, error) {
   133  	return newPebbleTempEngine(ctx, tempStorage, storeSpec)
   134  }
   135  
   136  var pebbleTempEngineTablePropertyCollectors = []func() pebble.TablePropertyCollector{
   137  	func() pebble.TablePropertyCollector { return &pebbleDeleteRangeCollector{} },
   138  }
   139  
   140  func newPebbleTempEngine(
   141  	ctx context.Context, tempStorage base.TempStorageConfig, storeSpec base.StoreSpec,
   142  ) (*pebbleTempEngine, fs.FS, error) {
   143  	// Default options as copied over from pebble/cmd/pebble/db.go
   144  	opts := DefaultPebbleOptions()
   145  	// Pebble doesn't currently support 0-size caches, so use a 128MB cache for
   146  	// now.
   147  	opts.Cache = pebble.NewCache(128 << 20)
   148  	defer opts.Cache.Unref()
   149  
   150  	// The Pebble temp engine does not use MVCC Encoding. Instead, the
   151  	// caller-provided key is used as-is (with the prefix prepended). See
   152  	// pebbleMap.makeKey and pebbleMap.makeKeyWithSequence on how this works.
   153  	// Use the default bytes.Compare-like comparer.
   154  	opts.Comparer = pebble.DefaultComparer
   155  	opts.DisableWAL = true
   156  	opts.TablePropertyCollectors = pebbleTempEngineTablePropertyCollectors
   157  
   158  	storageConfig := storageConfigFromTempStorageConfigAndStoreSpec(tempStorage, storeSpec)
   159  	if tempStorage.InMemory {
   160  		opts.FS = vfs.NewMem()
   161  		storageConfig.Dir = ""
   162  	}
   163  
   164  	p, err := NewPebble(
   165  		ctx,
   166  		PebbleConfig{
   167  			StorageConfig: storageConfig,
   168  			Opts:          opts,
   169  		},
   170  	)
   171  	if err != nil {
   172  		return nil, nil, err
   173  	}
   174  
   175  	return &pebbleTempEngine{db: p.db}, p, nil
   176  }