options.go 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804
  1. /*
  2. * Copyright 2017 Dgraph Labs, Inc. and Contributors
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package badger
  17. import (
  18. "fmt"
  19. "os"
  20. "reflect"
  21. "strconv"
  22. "strings"
  23. "time"
  24. "github.com/pkg/errors"
  25. "github.com/dgraph-io/badger/v4/options"
  26. "github.com/dgraph-io/badger/v4/table"
  27. "github.com/dgraph-io/badger/v4/y"
  28. "github.com/dgraph-io/ristretto/v2/z"
  29. )
  30. // Note: If you add a new option X make sure you also add a WithX method on Options.
  31. // Options are params for creating DB object.
  32. //
  33. // This package provides DefaultOptions which contains options that should
  34. // work for most applications. Consider using that as a starting point before
  35. // customizing it for your own needs.
  36. //
  37. // Each option X is documented on the WithX method.
  38. type Options struct {
  39. testOnlyOptions
  40. // Required options.
  41. Dir string
  42. ValueDir string
  43. // Usually modified options.
  44. SyncWrites bool
  45. NumVersionsToKeep int
  46. ReadOnly bool
  47. Logger Logger
  48. Compression options.CompressionType
  49. InMemory bool
  50. MetricsEnabled bool
  51. // Sets the Stream.numGo field
  52. NumGoroutines int
  53. // Fine tuning options.
  54. MemTableSize int64
  55. BaseTableSize int64
  56. BaseLevelSize int64
  57. LevelSizeMultiplier int
  58. TableSizeMultiplier int
  59. MaxLevels int
  60. VLogPercentile float64
  61. ValueThreshold int64
  62. NumMemtables int
  63. // Changing BlockSize across DB runs will not break badger. The block size is
  64. // read from the block index stored at the end of the table.
  65. BlockSize int
  66. BloomFalsePositive float64
  67. BlockCacheSize int64
  68. IndexCacheSize int64
  69. NumLevelZeroTables int
  70. NumLevelZeroTablesStall int
  71. ValueLogFileSize int64
  72. ValueLogMaxEntries uint32
  73. NumCompactors int
  74. CompactL0OnClose bool
  75. LmaxCompaction bool
  76. ZSTDCompressionLevel int
  77. // When set, checksum will be validated for each entry read from the value log file.
  78. VerifyValueChecksum bool
  79. // Encryption related options.
  80. EncryptionKey []byte // encryption key
  81. EncryptionKeyRotationDuration time.Duration // key rotation duration
  82. // BypassLockGuard will bypass the lock guard on badger. Bypassing lock
  83. // guard can cause data corruption if multiple badger instances are using
  84. // the same directory. Use this options with caution.
  85. BypassLockGuard bool
  86. // ChecksumVerificationMode decides when db should verify checksums for SSTable blocks.
  87. ChecksumVerificationMode options.ChecksumVerificationMode
  88. // DetectConflicts determines whether the transactions would be checked for
  89. // conflicts. The transactions can be processed at a higher rate when
  90. // conflict detection is disabled.
  91. DetectConflicts bool
  92. // NamespaceOffset specifies the offset from where the next 8 bytes contains the namespace.
  93. NamespaceOffset int
  94. // Magic version used by the application using badger to ensure that it doesn't open the DB
  95. // with incompatible data format.
  96. ExternalMagicVersion uint16
  97. // Transaction start and commit timestamps are managed by end-user.
  98. // This is only useful for databases built on top of Badger (like Dgraph).
  99. // Not recommended for most users.
  100. managedTxns bool
  101. // 4. Flags for testing purposes
  102. // ------------------------------
  103. maxBatchCount int64 // max entries in batch
  104. maxBatchSize int64 // max batch size in bytes
  105. maxValueThreshold float64
  106. }
  107. // DefaultOptions sets a list of recommended options for good performance.
  108. // Feel free to modify these to suit your needs with the WithX methods.
  109. func DefaultOptions(path string) Options {
  110. return Options{
  111. Dir: path,
  112. ValueDir: path,
  113. MemTableSize: 64 << 20,
  114. BaseTableSize: 2 << 20,
  115. BaseLevelSize: 10 << 20,
  116. TableSizeMultiplier: 2,
  117. LevelSizeMultiplier: 10,
  118. MaxLevels: 7,
  119. NumGoroutines: 8,
  120. MetricsEnabled: true,
  121. NumCompactors: 4, // Run at least 2 compactors. Zero-th compactor prioritizes L0.
  122. NumLevelZeroTables: 5,
  123. NumLevelZeroTablesStall: 15,
  124. NumMemtables: 5,
  125. BloomFalsePositive: 0.01,
  126. BlockSize: 4 * 1024,
  127. SyncWrites: false,
  128. NumVersionsToKeep: 1,
  129. CompactL0OnClose: false,
  130. VerifyValueChecksum: false,
  131. Compression: options.Snappy,
  132. BlockCacheSize: 256 << 20,
  133. IndexCacheSize: 0,
  134. // The following benchmarks were done on a 4 KB block size (default block size). The
  135. // compression is ratio supposed to increase with increasing compression level but since the
  136. // input for compression algorithm is small (4 KB), we don't get significant benefit at
  137. // level 3.
  138. // NOTE: The benchmarks are with DataDog ZSTD that requires CGO. Hence, no longer valid.
  139. // no_compression-16 10 502848865 ns/op 165.46 MB/s -
  140. // zstd_compression/level_1-16 7 739037966 ns/op 112.58 MB/s 2.93
  141. // zstd_compression/level_3-16 7 756950250 ns/op 109.91 MB/s 2.72
  142. // zstd_compression/level_15-16 1 11135686219 ns/op 7.47 MB/s 4.38
  143. // Benchmark code can be found in table/builder_test.go file
  144. ZSTDCompressionLevel: 1,
  145. // (2^30 - 1)*2 when mmapping < 2^31 - 1, max int32.
  146. // -1 so 2*ValueLogFileSize won't overflow on 32-bit systems.
  147. ValueLogFileSize: 1<<30 - 1,
  148. ValueLogMaxEntries: 1000000,
  149. VLogPercentile: 0.0,
  150. ValueThreshold: maxValueThreshold,
  151. Logger: defaultLogger(INFO),
  152. EncryptionKey: []byte{},
  153. EncryptionKeyRotationDuration: 10 * 24 * time.Hour, // Default 10 days.
  154. DetectConflicts: true,
  155. NamespaceOffset: -1,
  156. }
  157. }
  158. func buildTableOptions(db *DB) table.Options {
  159. opt := db.opt
  160. dk, err := db.registry.LatestDataKey()
  161. y.Check(err)
  162. return table.Options{
  163. ReadOnly: opt.ReadOnly,
  164. MetricsEnabled: db.opt.MetricsEnabled,
  165. TableSize: uint64(opt.BaseTableSize),
  166. BlockSize: opt.BlockSize,
  167. BloomFalsePositive: opt.BloomFalsePositive,
  168. ChkMode: opt.ChecksumVerificationMode,
  169. Compression: opt.Compression,
  170. ZSTDCompressionLevel: opt.ZSTDCompressionLevel,
  171. BlockCache: db.blockCache,
  172. IndexCache: db.indexCache,
  173. AllocPool: db.allocPool,
  174. DataKey: dk,
  175. }
  176. }
  177. const (
  178. maxValueThreshold = (1 << 20) // 1 MB
  179. )
  180. // LSMOnlyOptions follows from DefaultOptions, but sets a higher ValueThreshold
  181. // so values would be collocated with the LSM tree, with value log largely acting
  182. // as a write-ahead log only. These options would reduce the disk usage of value
  183. // log, and make Badger act more like a typical LSM tree.
  184. func LSMOnlyOptions(path string) Options {
  185. // Let's not set any other options, because they can cause issues with the
  186. // size of key-value a user can pass to Badger. For e.g., if we set
  187. // ValueLogFileSize to 64MB, a user can't pass a value more than that.
  188. // Setting it to ValueLogMaxEntries to 1000, can generate too many files.
  189. // These options are better configured on a usage basis, than broadly here.
  190. // The ValueThreshold is the most important setting a user needs to do to
  191. // achieve a heavier usage of LSM tree.
  192. // NOTE: If a user does not want to set 64KB as the ValueThreshold because
  193. // of performance reasons, 1KB would be a good option too, allowing
  194. // values smaller than 1KB to be collocated with the keys in the LSM tree.
  195. return DefaultOptions(path).WithValueThreshold(maxValueThreshold /* 1 MB */)
  196. }
  197. // parseCompression returns badger.compressionType and compression level given compression string
  198. // of format compression-type:compression-level
  199. func parseCompression(cStr string) (options.CompressionType, int, error) {
  200. cStrSplit := strings.Split(cStr, ":")
  201. cType := cStrSplit[0]
  202. level := 3
  203. var err error
  204. if len(cStrSplit) == 2 {
  205. level, err = strconv.Atoi(cStrSplit[1])
  206. y.Check(err)
  207. if level <= 0 {
  208. return 0, 0,
  209. errors.Errorf("ERROR: compression level(%v) must be greater than zero", level)
  210. }
  211. } else if len(cStrSplit) > 2 {
  212. return 0, 0, errors.Errorf("ERROR: Invalid badger.compression argument")
  213. }
  214. switch cType {
  215. case "zstd":
  216. return options.ZSTD, level, nil
  217. case "snappy":
  218. return options.Snappy, 0, nil
  219. case "none":
  220. return options.None, 0, nil
  221. }
  222. return 0, 0, errors.Errorf("ERROR: compression type (%s) invalid", cType)
  223. }
  224. // generateSuperFlag generates an identical SuperFlag string from the provided Options.
  225. func generateSuperFlag(options Options) string {
  226. superflag := ""
  227. v := reflect.ValueOf(&options).Elem()
  228. optionsStruct := v.Type()
  229. for i := 0; i < v.NumField(); i++ {
  230. if field := v.Field(i); field.CanInterface() {
  231. name := strings.ToLower(optionsStruct.Field(i).Name)
  232. kind := v.Field(i).Kind()
  233. switch kind {
  234. case reflect.Bool:
  235. superflag += name + "="
  236. superflag += fmt.Sprintf("%v; ", field.Bool())
  237. case reflect.Int, reflect.Int64:
  238. superflag += name + "="
  239. superflag += fmt.Sprintf("%v; ", field.Int())
  240. case reflect.Uint32, reflect.Uint64:
  241. superflag += name + "="
  242. superflag += fmt.Sprintf("%v; ", field.Uint())
  243. case reflect.Float64:
  244. superflag += name + "="
  245. superflag += fmt.Sprintf("%v; ", field.Float())
  246. case reflect.String:
  247. superflag += name + "="
  248. superflag += fmt.Sprintf("%v; ", field.String())
  249. default:
  250. continue
  251. }
  252. }
  253. }
  254. return superflag
  255. }
  256. // FromSuperFlag fills Options fields for each flag within the superflag. For
  257. // example, replacing the default Options.NumGoroutines:
  258. //
  259. // options := FromSuperFlag("numgoroutines=4", DefaultOptions(""))
  260. //
  261. // It's important to note that if you pass an empty Options struct, FromSuperFlag
  262. // will not fill it with default values. FromSuperFlag only writes to the fields
  263. // present within the superflag string (case insensitive).
  264. //
  265. // It specially handles compression subflag.
  266. // Valid options are {none,snappy,zstd:<level>}
  267. // Example: compression=zstd:3;
  268. // Unsupported: Options.Logger, Options.EncryptionKey
  269. func (opt Options) FromSuperFlag(superflag string) Options {
  270. // currentOptions act as a default value for the options superflag.
  271. currentOptions := generateSuperFlag(opt)
  272. currentOptions += "compression=;"
  273. flags := z.NewSuperFlag(superflag).MergeAndCheckDefault(currentOptions)
  274. v := reflect.ValueOf(&opt).Elem()
  275. optionsStruct := v.Type()
  276. for i := 0; i < v.NumField(); i++ {
  277. // only iterate over exported fields
  278. if field := v.Field(i); field.CanInterface() {
  279. // z.SuperFlag stores keys as lowercase, keep everything case
  280. // insensitive
  281. name := strings.ToLower(optionsStruct.Field(i).Name)
  282. if name == "compression" {
  283. // We will specially handle this later. Skip it here.
  284. continue
  285. }
  286. kind := v.Field(i).Kind()
  287. switch kind {
  288. case reflect.Bool:
  289. field.SetBool(flags.GetBool(name))
  290. case reflect.Int, reflect.Int64:
  291. field.SetInt(flags.GetInt64(name))
  292. case reflect.Uint32, reflect.Uint64:
  293. field.SetUint(flags.GetUint64(name))
  294. case reflect.Float64:
  295. field.SetFloat(flags.GetFloat64(name))
  296. case reflect.String:
  297. field.SetString(flags.GetString(name))
  298. }
  299. }
  300. }
  301. // Only update the options for special flags that were present in the input superflag.
  302. inputFlag := z.NewSuperFlag(superflag)
  303. if inputFlag.Has("compression") {
  304. ctype, clevel, err := parseCompression(flags.GetString("compression"))
  305. switch err {
  306. case nil:
  307. opt.Compression = ctype
  308. opt.ZSTDCompressionLevel = clevel
  309. default:
  310. ctype = options.CompressionType(flags.GetUint32("compression"))
  311. y.AssertTruef(ctype <= 2, "ERROR: Invalid format or compression type. Got: %s",
  312. flags.GetString("compression"))
  313. opt.Compression = ctype
  314. }
  315. }
  316. return opt
  317. }
  318. // WithDir returns a new Options value with Dir set to the given value.
  319. //
  320. // Dir is the path of the directory where key data will be stored in.
  321. // If it doesn't exist, Badger will try to create it for you.
  322. // This is set automatically to be the path given to `DefaultOptions`.
  323. func (opt Options) WithDir(val string) Options {
  324. opt.Dir = val
  325. return opt
  326. }
  327. // WithValueDir returns a new Options value with ValueDir set to the given value.
  328. //
  329. // ValueDir is the path of the directory where value data will be stored in.
  330. // If it doesn't exist, Badger will try to create it for you.
  331. // This is set automatically to be the path given to `DefaultOptions`.
  332. func (opt Options) WithValueDir(val string) Options {
  333. opt.ValueDir = val
  334. return opt
  335. }
  336. // WithSyncWrites returns a new Options value with SyncWrites set to the given value.
  337. //
  338. // Badger does all writes via mmap. So, all writes can survive process crashes or k8s environments
  339. // with SyncWrites set to false.
  340. //
  341. // When set to true, Badger would call an additional msync after writes to flush mmap buffer over to
  342. // disk to survive hard reboots. Most users of Badger should not need to do this.
  343. //
  344. // The default value of SyncWrites is false.
  345. func (opt Options) WithSyncWrites(val bool) Options {
  346. opt.SyncWrites = val
  347. return opt
  348. }
  349. // WithNumVersionsToKeep returns a new Options value with NumVersionsToKeep set to the given value.
  350. //
  351. // NumVersionsToKeep sets how many versions to keep per key at most.
  352. //
  353. // The default value of NumVersionsToKeep is 1.
  354. func (opt Options) WithNumVersionsToKeep(val int) Options {
  355. opt.NumVersionsToKeep = val
  356. return opt
  357. }
  358. // WithNumGoroutines sets the number of goroutines to be used in Stream.
  359. //
  360. // The default value of NumGoroutines is 8.
  361. func (opt Options) WithNumGoroutines(val int) Options {
  362. opt.NumGoroutines = val
  363. return opt
  364. }
  365. // WithReadOnly returns a new Options value with ReadOnly set to the given value.
  366. //
  367. // When ReadOnly is true the DB will be opened on read-only mode.
  368. // Multiple processes can open the same Badger DB.
  369. // Note: if the DB being opened had crashed before and has vlog data to be replayed,
  370. // ReadOnly will cause Open to fail with an appropriate message.
  371. //
  372. // The default value of ReadOnly is false.
  373. func (opt Options) WithReadOnly(val bool) Options {
  374. opt.ReadOnly = val
  375. return opt
  376. }
  377. // WithMetricsEnabled returns a new Options value with MetricsEnabled set to the given value.
  378. //
  379. // When MetricsEnabled is set to false, then the DB will be opened and no badger metrics
  380. // will be logged. Metrics are defined in metric.go file.
  381. //
  382. // This flag is useful for use cases like in Dgraph where we open temporary badger instances to
  383. // index data. In those cases we don't want badger metrics to be polluted with the noise from
  384. // those temporary instances.
  385. //
  386. // Default value is set to true
  387. func (opt Options) WithMetricsEnabled(val bool) Options {
  388. opt.MetricsEnabled = val
  389. return opt
  390. }
  391. // WithLogger returns a new Options value with Logger set to the given value.
  392. //
  393. // Logger provides a way to configure what logger each value of badger.DB uses.
  394. //
  395. // The default value of Logger writes to stderr using the log package from the Go standard library.
  396. func (opt Options) WithLogger(val Logger) Options {
  397. opt.Logger = val
  398. return opt
  399. }
  400. // WithLoggingLevel returns a new Options value with logging level of the
  401. // default logger set to the given value.
  402. // LoggingLevel sets the level of logging. It should be one of DEBUG, INFO,
  403. // WARNING or ERROR levels.
  404. //
  405. // The default value of LoggingLevel is INFO.
  406. func (opt Options) WithLoggingLevel(val loggingLevel) Options {
  407. opt.Logger = defaultLogger(val)
  408. return opt
  409. }
  410. // WithBaseTableSize returns a new Options value with BaseTableSize set to the given value.
  411. //
  412. // BaseTableSize sets the maximum size in bytes for LSM table or file in the base level.
  413. //
  414. // The default value of BaseTableSize is 2MB.
  415. func (opt Options) WithBaseTableSize(val int64) Options {
  416. opt.BaseTableSize = val
  417. return opt
  418. }
  419. // WithLevelSizeMultiplier returns a new Options value with LevelSizeMultiplier set to the given
  420. // value.
  421. //
  422. // LevelSizeMultiplier sets the ratio between the maximum sizes of contiguous levels in the LSM.
  423. // Once a level grows to be larger than this ratio allowed, the compaction process will be
  424. // triggered.
  425. //
  426. // The default value of LevelSizeMultiplier is 10.
  427. func (opt Options) WithLevelSizeMultiplier(val int) Options {
  428. opt.LevelSizeMultiplier = val
  429. return opt
  430. }
  431. // WithMaxLevels returns a new Options value with MaxLevels set to the given value.
  432. //
  433. // Maximum number of levels of compaction allowed in the LSM.
  434. //
  435. // The default value of MaxLevels is 7.
  436. func (opt Options) WithMaxLevels(val int) Options {
  437. opt.MaxLevels = val
  438. return opt
  439. }
  440. // WithValueThreshold returns a new Options value with ValueThreshold set to the given value.
  441. //
  442. // ValueThreshold sets the threshold used to decide whether a value is stored directly in the LSM
  443. // tree or separately in the log value files.
  444. //
  445. // The default value of ValueThreshold is 1 MB, and LSMOnlyOptions sets it to maxValueThreshold
  446. // which is set to 1 MB too.
  447. func (opt Options) WithValueThreshold(val int64) Options {
  448. opt.ValueThreshold = val
  449. return opt
  450. }
  451. // WithVLogPercentile returns a new Options value with ValLogPercentile set to given value.
  452. //
  453. // VLogPercentile with 0.0 means no dynamic thresholding is enabled.
  454. // MinThreshold value will always act as the value threshold.
  455. //
  456. // VLogPercentile with value 0.99 means 99 percentile of value will be put in LSM tree
  457. // and only 1 percent in vlog. The value threshold will be dynamically updated within the range of
  458. // [ValueThreshold, Options.maxValueThreshold]
  459. //
  460. // # Say VLogPercentile with 1.0 means threshold will eventually set to Options.maxValueThreshold
  461. //
  462. // The default value of VLogPercentile is 0.0.
  463. func (opt Options) WithVLogPercentile(t float64) Options {
  464. opt.VLogPercentile = t
  465. return opt
  466. }
  467. // WithNumMemtables returns a new Options value with NumMemtables set to the given value.
  468. //
  469. // NumMemtables sets the maximum number of tables to keep in memory before stalling.
  470. //
  471. // The default value of NumMemtables is 5.
  472. func (opt Options) WithNumMemtables(val int) Options {
  473. opt.NumMemtables = val
  474. return opt
  475. }
  476. // WithMemTableSize returns a new Options value with MemTableSize set to the given value.
  477. //
  478. // MemTableSize sets the maximum size in bytes for memtable table.
  479. //
  480. // The default value of MemTableSize is 64MB.
  481. func (opt Options) WithMemTableSize(val int64) Options {
  482. opt.MemTableSize = val
  483. return opt
  484. }
  485. // WithBloomFalsePositive returns a new Options value with BloomFalsePositive set
  486. // to the given value.
  487. //
  488. // BloomFalsePositive sets the false positive probability of the bloom filter in any SSTable.
  489. // Before reading a key from table, the bloom filter is checked for key existence.
  490. // BloomFalsePositive might impact read performance of DB. Lower BloomFalsePositive value might
  491. // consume more memory.
  492. //
  493. // The default value of BloomFalsePositive is 0.01.
  494. //
  495. // Setting this to 0 disables the bloom filter completely.
  496. func (opt Options) WithBloomFalsePositive(val float64) Options {
  497. opt.BloomFalsePositive = val
  498. return opt
  499. }
  500. // WithBlockSize returns a new Options value with BlockSize set to the given value.
  501. //
  502. // BlockSize sets the size of any block in SSTable. SSTable is divided into multiple blocks
  503. // internally. Each block is compressed using prefix diff encoding.
  504. //
  505. // The default value of BlockSize is 4KB.
  506. func (opt Options) WithBlockSize(val int) Options {
  507. opt.BlockSize = val
  508. return opt
  509. }
  510. // WithNumLevelZeroTables sets the maximum number of Level 0 tables before compaction starts.
  511. //
  512. // The default value of NumLevelZeroTables is 5.
  513. func (opt Options) WithNumLevelZeroTables(val int) Options {
  514. opt.NumLevelZeroTables = val
  515. return opt
  516. }
  517. // WithNumLevelZeroTablesStall sets the number of Level 0 tables that once reached causes the DB to
  518. // stall until compaction succeeds.
  519. //
  520. // The default value of NumLevelZeroTablesStall is 15.
  521. func (opt Options) WithNumLevelZeroTablesStall(val int) Options {
  522. opt.NumLevelZeroTablesStall = val
  523. return opt
  524. }
  525. // WithBaseLevelSize sets the maximum size target for the base level.
  526. //
  527. // The default value is 10MB.
  528. func (opt Options) WithBaseLevelSize(val int64) Options {
  529. opt.BaseLevelSize = val
  530. return opt
  531. }
  532. // WithValueLogFileSize sets the maximum size of a single value log file.
  533. //
  534. // The default value of ValueLogFileSize is 1GB.
  535. func (opt Options) WithValueLogFileSize(val int64) Options {
  536. opt.ValueLogFileSize = val
  537. return opt
  538. }
  539. // WithValueLogMaxEntries sets the maximum number of entries a value log file
  540. // can hold approximately. A actual size limit of a value log file is the
  541. // minimum of ValueLogFileSize and ValueLogMaxEntries.
  542. //
  543. // The default value of ValueLogMaxEntries is one million (1000000).
  544. func (opt Options) WithValueLogMaxEntries(val uint32) Options {
  545. opt.ValueLogMaxEntries = val
  546. return opt
  547. }
  548. // WithNumCompactors sets the number of compaction workers to run concurrently. Setting this to
  549. // zero stops compactions, which could eventually cause writes to block forever.
  550. //
  551. // The default value of NumCompactors is 4. One is dedicated just for L0 and L1.
  552. func (opt Options) WithNumCompactors(val int) Options {
  553. opt.NumCompactors = val
  554. return opt
  555. }
  556. // WithCompactL0OnClose determines whether Level 0 should be compacted before closing the DB. This
  557. // ensures that both reads and writes are efficient when the DB is opened later.
  558. //
  559. // The default value of CompactL0OnClose is false.
  560. func (opt Options) WithCompactL0OnClose(val bool) Options {
  561. opt.CompactL0OnClose = val
  562. return opt
  563. }
  564. // WithEncryptionKey is used to encrypt the data with AES. Type of AES is used based on the key
  565. // size. For example 16 bytes will use AES-128. 24 bytes will use AES-192. 32 bytes will
  566. // use AES-256.
  567. func (opt Options) WithEncryptionKey(key []byte) Options {
  568. opt.EncryptionKey = key
  569. return opt
  570. }
  571. // WithEncryptionKeyRotationDuration returns new Options value with the duration set to
  572. // the given value.
  573. //
  574. // Key Registry will use this duration to create new keys. If the previous generated
  575. // key exceed the given duration. Then the key registry will create new key.
  576. // The default value is set to 10 days.
  577. func (opt Options) WithEncryptionKeyRotationDuration(d time.Duration) Options {
  578. opt.EncryptionKeyRotationDuration = d
  579. return opt
  580. }
  581. // WithCompression is used to enable or disable compression. When compression is enabled, every
  582. // block will be compressed using the specified algorithm. This option doesn't affect existing
  583. // tables. Only the newly created tables will be compressed.
  584. //
  585. // The default compression algorithm used is snappy. Compression is enabled by default.
  586. func (opt Options) WithCompression(cType options.CompressionType) Options {
  587. opt.Compression = cType
  588. return opt
  589. }
  590. // WithVerifyValueChecksum is used to set VerifyValueChecksum. When VerifyValueChecksum is set to
  591. // true, checksum will be verified for every entry read from the value log. If the value is stored
  592. // in SST (value size less than value threshold) then the checksum validation will not be done.
  593. //
  594. // The default value of VerifyValueChecksum is False.
  595. func (opt Options) WithVerifyValueChecksum(val bool) Options {
  596. opt.VerifyValueChecksum = val
  597. return opt
  598. }
  599. // WithChecksumVerificationMode returns a new Options value with ChecksumVerificationMode set to
  600. // the given value.
  601. //
  602. // ChecksumVerificationMode indicates when the db should verify checksums for SSTable blocks.
  603. //
  604. // The default value of VerifyValueChecksum is options.NoVerification.
  605. func (opt Options) WithChecksumVerificationMode(cvMode options.ChecksumVerificationMode) Options {
  606. opt.ChecksumVerificationMode = cvMode
  607. return opt
  608. }
  609. // WithBlockCacheSize returns a new Options value with BlockCacheSize set to the given value.
  610. //
  611. // This value specifies how much data cache should hold in memory. A small size
  612. // of cache means lower memory consumption and lookups/iterations would take
  613. // longer. It is recommended to use a cache if you're using compression or encryption.
  614. // If compression and encryption both are disabled, adding a cache will lead to
  615. // unnecessary overhead which will affect the read performance. Setting size to
  616. // zero disables the cache altogether.
  617. //
  618. // Default value of BlockCacheSize is 256 MB.
  619. func (opt Options) WithBlockCacheSize(size int64) Options {
  620. opt.BlockCacheSize = size
  621. return opt
  622. }
  623. // WithInMemory returns a new Options value with Inmemory mode set to the given value.
  624. //
  625. // When badger is running in InMemory mode, everything is stored in memory. No value/sst files are
  626. // created. In case of a crash all data will be lost.
  627. func (opt Options) WithInMemory(b bool) Options {
  628. opt.InMemory = b
  629. return opt
  630. }
  631. // WithZSTDCompressionLevel returns a new Options value with ZSTDCompressionLevel set
  632. // to the given value.
  633. //
  634. // The ZSTD compression algorithm supports 20 compression levels. The higher the compression
  635. // level, the better is the compression ratio but lower is the performance. Lower levels
  636. // have better performance and higher levels have better compression ratios.
  637. // We recommend using level 1 ZSTD Compression Level. Any level higher than 1 seems to
  638. // deteriorate badger's performance.
  639. // The following benchmarks were done on a 4 KB block size (default block size). The compression is
  640. // ratio supposed to increase with increasing compression level but since the input for compression
  641. // algorithm is small (4 KB), we don't get significant benefit at level 3. It is advised to write
  642. // your own benchmarks before choosing a compression algorithm or level.
  643. //
  644. // NOTE: The benchmarks are with DataDog ZSTD that requires CGO. Hence, no longer valid.
  645. // no_compression-16 10 502848865 ns/op 165.46 MB/s -
  646. // zstd_compression/level_1-16 7 739037966 ns/op 112.58 MB/s 2.93
  647. // zstd_compression/level_3-16 7 756950250 ns/op 109.91 MB/s 2.72
  648. // zstd_compression/level_15-16 1 11135686219 ns/op 7.47 MB/s 4.38
  649. // Benchmark code can be found in table/builder_test.go file
  650. func (opt Options) WithZSTDCompressionLevel(cLevel int) Options {
  651. opt.ZSTDCompressionLevel = cLevel
  652. return opt
  653. }
  654. // WithBypassLockGuard returns a new Options value with BypassLockGuard
  655. // set to the given value.
  656. //
  657. // When BypassLockGuard option is set, badger will not acquire a lock on the
  658. // directory. This could lead to data corruption if multiple badger instances
  659. // write to the same data directory. Use this option with caution.
  660. //
  661. // The default value of BypassLockGuard is false.
  662. func (opt Options) WithBypassLockGuard(b bool) Options {
  663. opt.BypassLockGuard = b
  664. return opt
  665. }
  666. // WithIndexCacheSize returns a new Options value with IndexCacheSize set to
  667. // the given value.
  668. //
  669. // This value specifies how much memory should be used by table indices. These
  670. // indices include the block offsets and the bloomfilters. Badger uses bloom
  671. // filters to speed up lookups. Each table has its own bloom
  672. // filter and each bloom filter is approximately of 5 MB.
  673. //
  674. // Zero value for IndexCacheSize means all the indices will be kept in
  675. // memory and the cache is disabled.
  676. //
  677. // The default value of IndexCacheSize is 0 which means all indices are kept in
  678. // memory.
  679. func (opt Options) WithIndexCacheSize(size int64) Options {
  680. opt.IndexCacheSize = size
  681. return opt
  682. }
  683. // WithDetectConflicts returns a new Options value with DetectConflicts set to the given value.
  684. //
  685. // Detect conflicts options determines if the transactions would be checked for
  686. // conflicts before committing them. When this option is set to false
  687. // (detectConflicts=false) badger can process transactions at a higher rate.
  688. // Setting this options to false might be useful when the user application
  689. // deals with conflict detection and resolution.
  690. //
  691. // The default value of Detect conflicts is True.
  692. func (opt Options) WithDetectConflicts(b bool) Options {
  693. opt.DetectConflicts = b
  694. return opt
  695. }
  696. // WithNamespaceOffset returns a new Options value with NamespaceOffset set to the given value. DB
  697. // will expect the namespace in each key at the 8 bytes starting from NamespaceOffset. A negative
  698. // value means that namespace is not stored in the key.
  699. //
  700. // The default value for NamespaceOffset is -1.
  701. func (opt Options) WithNamespaceOffset(offset int) Options {
  702. opt.NamespaceOffset = offset
  703. return opt
  704. }
  705. // WithExternalMagic returns a new Options value with ExternalMagicVersion set to the given value.
  706. // The DB would fail to start if either the internal or the external magic number fails validated.
  707. func (opt Options) WithExternalMagic(magic uint16) Options {
  708. opt.ExternalMagicVersion = magic
  709. return opt
  710. }
  711. func (opt Options) getFileFlags() int {
  712. var flags int
  713. // opt.SyncWrites would be using msync to sync. All writes go through mmap.
  714. if opt.ReadOnly {
  715. flags |= os.O_RDONLY
  716. } else {
  717. flags |= os.O_RDWR
  718. }
  719. return flags
  720. }