| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791 |
- /*
- * SPDX-FileCopyrightText: © Hypermode Inc. <hello@hypermode.com>
- * SPDX-License-Identifier: Apache-2.0
- */
- package badger
- import (
- "fmt"
- "os"
- "reflect"
- "strconv"
- "strings"
- "time"
- "github.com/dgraph-io/badger/v4/options"
- "github.com/dgraph-io/badger/v4/table"
- "github.com/dgraph-io/badger/v4/y"
- "github.com/dgraph-io/ristretto/v2/z"
- )
- // Note: If you add a new option X make sure you also add a WithX method on Options.
- // Options are params for creating DB object.
- //
- // This package provides DefaultOptions which contains options that should
- // work for most applications. Consider using that as a starting point before
- // customizing it for your own needs.
- //
- // Each option X is documented on the WithX method.
- type Options struct {
- testOnlyOptions
- // Required options.
- Dir string
- ValueDir string
- // Usually modified options.
- SyncWrites bool
- NumVersionsToKeep int
- ReadOnly bool
- Logger Logger
- Compression options.CompressionType
- InMemory bool
- MetricsEnabled bool
- // Sets the Stream.numGo field
- NumGoroutines int
- // Fine tuning options.
- MemTableSize int64
- BaseTableSize int64
- BaseLevelSize int64
- LevelSizeMultiplier int
- TableSizeMultiplier int
- MaxLevels int
- VLogPercentile float64
- ValueThreshold int64
- NumMemtables int
- // Changing BlockSize across DB runs will not break badger. The block size is
- // read from the block index stored at the end of the table.
- BlockSize int
- BloomFalsePositive float64
- BlockCacheSize int64
- IndexCacheSize int64
- NumLevelZeroTables int
- NumLevelZeroTablesStall int
- ValueLogFileSize int64
- ValueLogMaxEntries uint32
- NumCompactors int
- CompactL0OnClose bool
- LmaxCompaction bool
- ZSTDCompressionLevel int
- // When set, checksum will be validated for each entry read from the value log file.
- VerifyValueChecksum bool
- // Encryption related options.
- EncryptionKey []byte // encryption key
- EncryptionKeyRotationDuration time.Duration // key rotation duration
- // BypassLockGuard will bypass the lock guard on badger. Bypassing lock
- // guard can cause data corruption if multiple badger instances are using
- // the same directory. Use this options with caution.
- BypassLockGuard bool
- // ChecksumVerificationMode decides when db should verify checksums for SSTable blocks.
- ChecksumVerificationMode options.ChecksumVerificationMode
- // DetectConflicts determines whether the transactions would be checked for
- // conflicts. The transactions can be processed at a higher rate when
- // conflict detection is disabled.
- DetectConflicts bool
- // NamespaceOffset specifies the offset from where the next 8 bytes contains the namespace.
- NamespaceOffset int
- // Magic version used by the application using badger to ensure that it doesn't open the DB
- // with incompatible data format.
- ExternalMagicVersion uint16
- // Transaction start and commit timestamps are managed by end-user.
- // This is only useful for databases built on top of Badger (like Dgraph).
- // Not recommended for most users.
- managedTxns bool
- // 4. Flags for testing purposes
- // ------------------------------
- maxBatchCount int64 // max entries in batch
- maxBatchSize int64 // max batch size in bytes
- maxValueThreshold float64
- }
- // DefaultOptions sets a list of recommended options for good performance.
- // Feel free to modify these to suit your needs with the WithX methods.
- func DefaultOptions(path string) Options {
- return Options{
- Dir: path,
- ValueDir: path,
- MemTableSize: 64 << 20,
- BaseTableSize: 2 << 20,
- BaseLevelSize: 10 << 20,
- TableSizeMultiplier: 2,
- LevelSizeMultiplier: 10,
- MaxLevels: 7,
- NumGoroutines: 8,
- MetricsEnabled: true,
- NumCompactors: 4, // Run at least 2 compactors. Zero-th compactor prioritizes L0.
- NumLevelZeroTables: 5,
- NumLevelZeroTablesStall: 15,
- NumMemtables: 5,
- BloomFalsePositive: 0.01,
- BlockSize: 4 * 1024,
- SyncWrites: false,
- NumVersionsToKeep: 1,
- CompactL0OnClose: false,
- VerifyValueChecksum: false,
- Compression: options.Snappy,
- BlockCacheSize: 256 << 20,
- IndexCacheSize: 0,
- // The following benchmarks were done on a 4 KB block size (default block size). The
- // compression is ratio supposed to increase with increasing compression level but since the
- // input for compression algorithm is small (4 KB), we don't get significant benefit at
- // level 3.
- // NOTE: The benchmarks are with DataDog ZSTD that requires CGO. Hence, no longer valid.
- // no_compression-16 10 502848865 ns/op 165.46 MB/s -
- // zstd_compression/level_1-16 7 739037966 ns/op 112.58 MB/s 2.93
- // zstd_compression/level_3-16 7 756950250 ns/op 109.91 MB/s 2.72
- // zstd_compression/level_15-16 1 11135686219 ns/op 7.47 MB/s 4.38
- // Benchmark code can be found in table/builder_test.go file
- ZSTDCompressionLevel: 1,
- // (2^30 - 1)*2 when mmapping < 2^31 - 1, max int32.
- // -1 so 2*ValueLogFileSize won't overflow on 32-bit systems.
- ValueLogFileSize: 1<<30 - 1,
- ValueLogMaxEntries: 1000000,
- VLogPercentile: 0.0,
- ValueThreshold: maxValueThreshold,
- Logger: defaultLogger(INFO),
- EncryptionKey: []byte{},
- EncryptionKeyRotationDuration: 10 * 24 * time.Hour, // Default 10 days.
- DetectConflicts: true,
- NamespaceOffset: -1,
- }
- }
- func buildTableOptions(db *DB) table.Options {
- opt := db.opt
- dk, err := db.registry.LatestDataKey()
- y.Check(err)
- return table.Options{
- ReadOnly: opt.ReadOnly,
- MetricsEnabled: db.opt.MetricsEnabled,
- TableSize: uint64(opt.BaseTableSize),
- BlockSize: opt.BlockSize,
- BloomFalsePositive: opt.BloomFalsePositive,
- ChkMode: opt.ChecksumVerificationMode,
- Compression: opt.Compression,
- ZSTDCompressionLevel: opt.ZSTDCompressionLevel,
- BlockCache: db.blockCache,
- IndexCache: db.indexCache,
- AllocPool: db.allocPool,
- DataKey: dk,
- }
- }
- const (
- maxValueThreshold = (1 << 20) // 1 MB
- )
- // LSMOnlyOptions follows from DefaultOptions, but sets a higher ValueThreshold
- // so values would be collocated with the LSM tree, with value log largely acting
- // as a write-ahead log only. These options would reduce the disk usage of value
- // log, and make Badger act more like a typical LSM tree.
- func LSMOnlyOptions(path string) Options {
- // Let's not set any other options, because they can cause issues with the
- // size of key-value a user can pass to Badger. For e.g., if we set
- // ValueLogFileSize to 64MB, a user can't pass a value more than that.
- // Setting it to ValueLogMaxEntries to 1000, can generate too many files.
- // These options are better configured on a usage basis, than broadly here.
- // The ValueThreshold is the most important setting a user needs to do to
- // achieve a heavier usage of LSM tree.
- // NOTE: If a user does not want to set 64KB as the ValueThreshold because
- // of performance reasons, 1KB would be a good option too, allowing
- // values smaller than 1KB to be collocated with the keys in the LSM tree.
- return DefaultOptions(path).WithValueThreshold(maxValueThreshold /* 1 MB */)
- }
- // parseCompression returns badger.compressionType and compression level given compression string
- // of format compression-type:compression-level
- func parseCompression(cStr string) (options.CompressionType, int, error) {
- cStrSplit := strings.Split(cStr, ":")
- cType := cStrSplit[0]
- level := 3
- var err error
- if len(cStrSplit) == 2 {
- level, err = strconv.Atoi(cStrSplit[1])
- y.Check(err)
- if level <= 0 {
- return 0, 0,
- fmt.Errorf("ERROR: compression level(%v) must be greater than zero", level)
- }
- } else if len(cStrSplit) > 2 {
- return 0, 0, fmt.Errorf("ERROR: Invalid badger.compression argument")
- }
- switch cType {
- case "zstd":
- return options.ZSTD, level, nil
- case "snappy":
- return options.Snappy, 0, nil
- case "none":
- return options.None, 0, nil
- }
- return 0, 0, fmt.Errorf("ERROR: compression type (%s) invalid", cType)
- }
- // generateSuperFlag generates an identical SuperFlag string from the provided Options.
- func generateSuperFlag(options Options) string {
- superflag := ""
- v := reflect.ValueOf(&options).Elem()
- optionsStruct := v.Type()
- for i := 0; i < v.NumField(); i++ {
- if field := v.Field(i); field.CanInterface() {
- name := strings.ToLower(optionsStruct.Field(i).Name)
- kind := v.Field(i).Kind()
- switch kind {
- case reflect.Bool:
- superflag += name + "="
- superflag += fmt.Sprintf("%v; ", field.Bool())
- case reflect.Int, reflect.Int64:
- superflag += name + "="
- superflag += fmt.Sprintf("%v; ", field.Int())
- case reflect.Uint32, reflect.Uint64:
- superflag += name + "="
- superflag += fmt.Sprintf("%v; ", field.Uint())
- case reflect.Float64:
- superflag += name + "="
- superflag += fmt.Sprintf("%v; ", field.Float())
- case reflect.String:
- superflag += name + "="
- superflag += fmt.Sprintf("%v; ", field.String())
- default:
- continue
- }
- }
- }
- return superflag
- }
- // FromSuperFlag fills Options fields for each flag within the superflag. For
- // example, replacing the default Options.NumGoroutines:
- //
- // options := FromSuperFlag("numgoroutines=4", DefaultOptions(""))
- //
- // It's important to note that if you pass an empty Options struct, FromSuperFlag
- // will not fill it with default values. FromSuperFlag only writes to the fields
- // present within the superflag string (case insensitive).
- //
- // It specially handles compression subflag.
- // Valid options are {none,snappy,zstd:<level>}
- // Example: compression=zstd:3;
- // Unsupported: Options.Logger, Options.EncryptionKey
- func (opt Options) FromSuperFlag(superflag string) Options {
- // currentOptions act as a default value for the options superflag.
- currentOptions := generateSuperFlag(opt)
- currentOptions += "compression=;"
- flags := z.NewSuperFlag(superflag).MergeAndCheckDefault(currentOptions)
- v := reflect.ValueOf(&opt).Elem()
- optionsStruct := v.Type()
- for i := 0; i < v.NumField(); i++ {
- // only iterate over exported fields
- if field := v.Field(i); field.CanInterface() {
- // z.SuperFlag stores keys as lowercase, keep everything case
- // insensitive
- name := strings.ToLower(optionsStruct.Field(i).Name)
- if name == "compression" {
- // We will specially handle this later. Skip it here.
- continue
- }
- kind := v.Field(i).Kind()
- switch kind {
- case reflect.Bool:
- field.SetBool(flags.GetBool(name))
- case reflect.Int, reflect.Int64:
- field.SetInt(flags.GetInt64(name))
- case reflect.Uint32, reflect.Uint64:
- field.SetUint(flags.GetUint64(name))
- case reflect.Float64:
- field.SetFloat(flags.GetFloat64(name))
- case reflect.String:
- field.SetString(flags.GetString(name))
- }
- }
- }
- // Only update the options for special flags that were present in the input superflag.
- inputFlag := z.NewSuperFlag(superflag)
- if inputFlag.Has("compression") {
- ctype, clevel, err := parseCompression(flags.GetString("compression"))
- switch err {
- case nil:
- opt.Compression = ctype
- opt.ZSTDCompressionLevel = clevel
- default:
- ctype = options.CompressionType(flags.GetUint32("compression"))
- y.AssertTruef(ctype <= 2, "ERROR: Invalid format or compression type. Got: %s",
- flags.GetString("compression"))
- opt.Compression = ctype
- }
- }
- return opt
- }
- // WithDir returns a new Options value with Dir set to the given value.
- //
- // Dir is the path of the directory where key data will be stored in.
- // If it doesn't exist, Badger will try to create it for you.
- // This is set automatically to be the path given to `DefaultOptions`.
- func (opt Options) WithDir(val string) Options {
- opt.Dir = val
- return opt
- }
- // WithValueDir returns a new Options value with ValueDir set to the given value.
- //
- // ValueDir is the path of the directory where value data will be stored in.
- // If it doesn't exist, Badger will try to create it for you.
- // This is set automatically to be the path given to `DefaultOptions`.
- func (opt Options) WithValueDir(val string) Options {
- opt.ValueDir = val
- return opt
- }
- // WithSyncWrites returns a new Options value with SyncWrites set to the given value.
- //
- // Badger does all writes via mmap. So, all writes can survive process crashes or k8s environments
- // with SyncWrites set to false.
- //
- // When set to true, Badger would call an additional msync after writes to flush mmap buffer over to
- // disk to survive hard reboots. Most users of Badger should not need to do this.
- //
- // The default value of SyncWrites is false.
- func (opt Options) WithSyncWrites(val bool) Options {
- opt.SyncWrites = val
- return opt
- }
- // WithNumVersionsToKeep returns a new Options value with NumVersionsToKeep set to the given value.
- //
- // NumVersionsToKeep sets how many versions to keep per key at most.
- //
- // The default value of NumVersionsToKeep is 1.
- func (opt Options) WithNumVersionsToKeep(val int) Options {
- opt.NumVersionsToKeep = val
- return opt
- }
- // WithNumGoroutines sets the number of goroutines to be used in Stream.
- //
- // The default value of NumGoroutines is 8.
- func (opt Options) WithNumGoroutines(val int) Options {
- opt.NumGoroutines = val
- return opt
- }
- // WithReadOnly returns a new Options value with ReadOnly set to the given value.
- //
- // When ReadOnly is true the DB will be opened on read-only mode.
- // Multiple processes can open the same Badger DB.
- // Note: if the DB being opened had crashed before and has vlog data to be replayed,
- // ReadOnly will cause Open to fail with an appropriate message.
- //
- // The default value of ReadOnly is false.
- func (opt Options) WithReadOnly(val bool) Options {
- opt.ReadOnly = val
- return opt
- }
- // WithMetricsEnabled returns a new Options value with MetricsEnabled set to the given value.
- //
- // When MetricsEnabled is set to false, then the DB will be opened and no badger metrics
- // will be logged. Metrics are defined in metric.go file.
- //
- // This flag is useful for use cases like in Dgraph where we open temporary badger instances to
- // index data. In those cases we don't want badger metrics to be polluted with the noise from
- // those temporary instances.
- //
- // Default value is set to true
- func (opt Options) WithMetricsEnabled(val bool) Options {
- opt.MetricsEnabled = val
- return opt
- }
- // WithLogger returns a new Options value with Logger set to the given value.
- //
- // Logger provides a way to configure what logger each value of badger.DB uses.
- //
- // The default value of Logger writes to stderr using the log package from the Go standard library.
- func (opt Options) WithLogger(val Logger) Options {
- opt.Logger = val
- return opt
- }
- // WithLoggingLevel returns a new Options value with logging level of the
- // default logger set to the given value.
- // LoggingLevel sets the level of logging. It should be one of DEBUG, INFO,
- // WARNING or ERROR levels.
- //
- // The default value of LoggingLevel is INFO.
- func (opt Options) WithLoggingLevel(val loggingLevel) Options {
- opt.Logger = defaultLogger(val)
- return opt
- }
- // WithBaseTableSize returns a new Options value with BaseTableSize set to the given value.
- //
- // BaseTableSize sets the maximum size in bytes for LSM table or file in the base level.
- //
- // The default value of BaseTableSize is 2MB.
- func (opt Options) WithBaseTableSize(val int64) Options {
- opt.BaseTableSize = val
- return opt
- }
- // WithLevelSizeMultiplier returns a new Options value with LevelSizeMultiplier set to the given
- // value.
- //
- // LevelSizeMultiplier sets the ratio between the maximum sizes of contiguous levels in the LSM.
- // Once a level grows to be larger than this ratio allowed, the compaction process will be
- // triggered.
- //
- // The default value of LevelSizeMultiplier is 10.
- func (opt Options) WithLevelSizeMultiplier(val int) Options {
- opt.LevelSizeMultiplier = val
- return opt
- }
- // WithMaxLevels returns a new Options value with MaxLevels set to the given value.
- //
- // Maximum number of levels of compaction allowed in the LSM.
- //
- // The default value of MaxLevels is 7.
- func (opt Options) WithMaxLevels(val int) Options {
- opt.MaxLevels = val
- return opt
- }
- // WithValueThreshold returns a new Options value with ValueThreshold set to the given value.
- //
- // ValueThreshold sets the threshold used to decide whether a value is stored directly in the LSM
- // tree or separately in the log value files.
- //
- // The default value of ValueThreshold is 1 MB, and LSMOnlyOptions sets it to maxValueThreshold
- // which is set to 1 MB too.
- func (opt Options) WithValueThreshold(val int64) Options {
- opt.ValueThreshold = val
- return opt
- }
- // WithVLogPercentile returns a new Options value with ValLogPercentile set to given value.
- //
- // VLogPercentile with 0.0 means no dynamic thresholding is enabled.
- // MinThreshold value will always act as the value threshold.
- //
- // VLogPercentile with value 0.99 means 99 percentile of value will be put in LSM tree
- // and only 1 percent in vlog. The value threshold will be dynamically updated within the range of
- // [ValueThreshold, Options.maxValueThreshold]
- //
- // # Say VLogPercentile with 1.0 means threshold will eventually set to Options.maxValueThreshold
- //
- // The default value of VLogPercentile is 0.0.
- func (opt Options) WithVLogPercentile(t float64) Options {
- opt.VLogPercentile = t
- return opt
- }
- // WithNumMemtables returns a new Options value with NumMemtables set to the given value.
- //
- // NumMemtables sets the maximum number of tables to keep in memory before stalling.
- //
- // The default value of NumMemtables is 5.
- func (opt Options) WithNumMemtables(val int) Options {
- opt.NumMemtables = val
- return opt
- }
- // WithMemTableSize returns a new Options value with MemTableSize set to the given value.
- //
- // MemTableSize sets the maximum size in bytes for memtable table.
- //
- // The default value of MemTableSize is 64MB.
- func (opt Options) WithMemTableSize(val int64) Options {
- opt.MemTableSize = val
- return opt
- }
- // WithBloomFalsePositive returns a new Options value with BloomFalsePositive set
- // to the given value.
- //
- // BloomFalsePositive sets the false positive probability of the bloom filter in any SSTable.
- // Before reading a key from table, the bloom filter is checked for key existence.
- // BloomFalsePositive might impact read performance of DB. Lower BloomFalsePositive value might
- // consume more memory.
- //
- // The default value of BloomFalsePositive is 0.01.
- //
- // Setting this to 0 disables the bloom filter completely.
- func (opt Options) WithBloomFalsePositive(val float64) Options {
- opt.BloomFalsePositive = val
- return opt
- }
- // WithBlockSize returns a new Options value with BlockSize set to the given value.
- //
- // BlockSize sets the size of any block in SSTable. SSTable is divided into multiple blocks
- // internally. Each block is compressed using prefix diff encoding.
- //
- // The default value of BlockSize is 4KB.
- func (opt Options) WithBlockSize(val int) Options {
- opt.BlockSize = val
- return opt
- }
- // WithNumLevelZeroTables sets the maximum number of Level 0 tables before compaction starts.
- //
- // The default value of NumLevelZeroTables is 5.
- func (opt Options) WithNumLevelZeroTables(val int) Options {
- opt.NumLevelZeroTables = val
- return opt
- }
- // WithNumLevelZeroTablesStall sets the number of Level 0 tables that once reached causes the DB to
- // stall until compaction succeeds.
- //
- // The default value of NumLevelZeroTablesStall is 15.
- func (opt Options) WithNumLevelZeroTablesStall(val int) Options {
- opt.NumLevelZeroTablesStall = val
- return opt
- }
- // WithBaseLevelSize sets the maximum size target for the base level.
- //
- // The default value is 10MB.
- func (opt Options) WithBaseLevelSize(val int64) Options {
- opt.BaseLevelSize = val
- return opt
- }
- // WithValueLogFileSize sets the maximum size of a single value log file.
- //
- // The default value of ValueLogFileSize is 1GB.
- func (opt Options) WithValueLogFileSize(val int64) Options {
- opt.ValueLogFileSize = val
- return opt
- }
- // WithValueLogMaxEntries sets the maximum number of entries a value log file
- // can hold approximately. A actual size limit of a value log file is the
- // minimum of ValueLogFileSize and ValueLogMaxEntries.
- //
- // The default value of ValueLogMaxEntries is one million (1000000).
- func (opt Options) WithValueLogMaxEntries(val uint32) Options {
- opt.ValueLogMaxEntries = val
- return opt
- }
- // WithNumCompactors sets the number of compaction workers to run concurrently. Setting this to
- // zero stops compactions, which could eventually cause writes to block forever.
- //
- // The default value of NumCompactors is 4. One is dedicated just for L0 and L1.
- func (opt Options) WithNumCompactors(val int) Options {
- opt.NumCompactors = val
- return opt
- }
- // WithCompactL0OnClose determines whether Level 0 should be compacted before closing the DB. This
- // ensures that both reads and writes are efficient when the DB is opened later.
- //
- // The default value of CompactL0OnClose is false.
- func (opt Options) WithCompactL0OnClose(val bool) Options {
- opt.CompactL0OnClose = val
- return opt
- }
- // WithEncryptionKey is used to encrypt the data with AES. Type of AES is used based on the key
- // size. For example 16 bytes will use AES-128. 24 bytes will use AES-192. 32 bytes will
- // use AES-256.
- func (opt Options) WithEncryptionKey(key []byte) Options {
- opt.EncryptionKey = key
- return opt
- }
- // WithEncryptionKeyRotationDuration returns new Options value with the duration set to
- // the given value.
- //
- // Key Registry will use this duration to create new keys. If the previous generated
- // key exceed the given duration. Then the key registry will create new key.
- // The default value is set to 10 days.
- func (opt Options) WithEncryptionKeyRotationDuration(d time.Duration) Options {
- opt.EncryptionKeyRotationDuration = d
- return opt
- }
- // WithCompression is used to enable or disable compression. When compression is enabled, every
- // block will be compressed using the specified algorithm. This option doesn't affect existing
- // tables. Only the newly created tables will be compressed.
- //
- // The default compression algorithm used is snappy. Compression is enabled by default.
- func (opt Options) WithCompression(cType options.CompressionType) Options {
- opt.Compression = cType
- return opt
- }
- // WithVerifyValueChecksum is used to set VerifyValueChecksum. When VerifyValueChecksum is set to
- // true, checksum will be verified for every entry read from the value log. If the value is stored
- // in SST (value size less than value threshold) then the checksum validation will not be done.
- //
- // The default value of VerifyValueChecksum is False.
- func (opt Options) WithVerifyValueChecksum(val bool) Options {
- opt.VerifyValueChecksum = val
- return opt
- }
- // WithChecksumVerificationMode returns a new Options value with ChecksumVerificationMode set to
- // the given value.
- //
- // ChecksumVerificationMode indicates when the db should verify checksums for SSTable blocks.
- //
- // The default value of VerifyValueChecksum is options.NoVerification.
- func (opt Options) WithChecksumVerificationMode(cvMode options.ChecksumVerificationMode) Options {
- opt.ChecksumVerificationMode = cvMode
- return opt
- }
- // WithBlockCacheSize returns a new Options value with BlockCacheSize set to the given value.
- //
- // This value specifies how much data cache should hold in memory. A small size
- // of cache means lower memory consumption and lookups/iterations would take
- // longer. It is recommended to use a cache if you're using compression or encryption.
- // If compression and encryption both are disabled, adding a cache will lead to
- // unnecessary overhead which will affect the read performance. Setting size to
- // zero disables the cache altogether.
- //
- // Default value of BlockCacheSize is 256 MB.
- func (opt Options) WithBlockCacheSize(size int64) Options {
- opt.BlockCacheSize = size
- return opt
- }
- // WithInMemory returns a new Options value with Inmemory mode set to the given value.
- //
- // When badger is running in InMemory mode, everything is stored in memory. No value/sst files are
- // created. In case of a crash all data will be lost.
- func (opt Options) WithInMemory(b bool) Options {
- opt.InMemory = b
- return opt
- }
- // WithZSTDCompressionLevel returns a new Options value with ZSTDCompressionLevel set
- // to the given value.
- //
- // The ZSTD compression algorithm supports 20 compression levels. The higher the compression
- // level, the better is the compression ratio but lower is the performance. Lower levels
- // have better performance and higher levels have better compression ratios.
- // We recommend using level 1 ZSTD Compression Level. Any level higher than 1 seems to
- // deteriorate badger's performance.
- // The following benchmarks were done on a 4 KB block size (default block size). The compression is
- // ratio supposed to increase with increasing compression level but since the input for compression
- // algorithm is small (4 KB), we don't get significant benefit at level 3. It is advised to write
- // your own benchmarks before choosing a compression algorithm or level.
- //
- // NOTE: The benchmarks are with DataDog ZSTD that requires CGO. Hence, no longer valid.
- // no_compression-16 10 502848865 ns/op 165.46 MB/s -
- // zstd_compression/level_1-16 7 739037966 ns/op 112.58 MB/s 2.93
- // zstd_compression/level_3-16 7 756950250 ns/op 109.91 MB/s 2.72
- // zstd_compression/level_15-16 1 11135686219 ns/op 7.47 MB/s 4.38
- // Benchmark code can be found in table/builder_test.go file
- func (opt Options) WithZSTDCompressionLevel(cLevel int) Options {
- opt.ZSTDCompressionLevel = cLevel
- return opt
- }
- // WithBypassLockGuard returns a new Options value with BypassLockGuard
- // set to the given value.
- //
- // When BypassLockGuard option is set, badger will not acquire a lock on the
- // directory. This could lead to data corruption if multiple badger instances
- // write to the same data directory. Use this option with caution.
- //
- // The default value of BypassLockGuard is false.
- func (opt Options) WithBypassLockGuard(b bool) Options {
- opt.BypassLockGuard = b
- return opt
- }
- // WithIndexCacheSize returns a new Options value with IndexCacheSize set to
- // the given value.
- //
- // This value specifies how much memory should be used by table indices. These
- // indices include the block offsets and the bloomfilters. Badger uses bloom
- // filters to speed up lookups. Each table has its own bloom
- // filter and each bloom filter is approximately of 5 MB.
- //
- // Zero value for IndexCacheSize means all the indices will be kept in
- // memory and the cache is disabled.
- //
- // The default value of IndexCacheSize is 0 which means all indices are kept in
- // memory.
- func (opt Options) WithIndexCacheSize(size int64) Options {
- opt.IndexCacheSize = size
- return opt
- }
- // WithDetectConflicts returns a new Options value with DetectConflicts set to the given value.
- //
- // Detect conflicts options determines if the transactions would be checked for
- // conflicts before committing them. When this option is set to false
- // (detectConflicts=false) badger can process transactions at a higher rate.
- // Setting this options to false might be useful when the user application
- // deals with conflict detection and resolution.
- //
- // The default value of Detect conflicts is True.
- func (opt Options) WithDetectConflicts(b bool) Options {
- opt.DetectConflicts = b
- return opt
- }
- // WithNamespaceOffset returns a new Options value with NamespaceOffset set to the given value. DB
- // will expect the namespace in each key at the 8 bytes starting from NamespaceOffset. A negative
- // value means that namespace is not stored in the key.
- //
- // The default value for NamespaceOffset is -1.
- func (opt Options) WithNamespaceOffset(offset int) Options {
- opt.NamespaceOffset = offset
- return opt
- }
- // WithExternalMagic returns a new Options value with ExternalMagicVersion set to the given value.
- // The DB would fail to start if either the internal or the external magic number fails validated.
- func (opt Options) WithExternalMagic(magic uint16) Options {
- opt.ExternalMagicVersion = magic
- return opt
- }
- func (opt Options) getFileFlags() int {
- var flags int
- // opt.SyncWrites would be using msync to sync. All writes go through mmap.
- if opt.ReadOnly {
- flags |= os.O_RDONLY
- } else {
- flags |= os.O_RDWR
- }
- return flags
- }
|