-
Notifications
You must be signed in to change notification settings - Fork 372
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
667b6d0
commit b322ff5
Showing
7 changed files
with
173 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
//go:build !rocksdb | ||
// +build !rocksdb | ||
|
||
package opendb | ||
|
||
import ( | ||
"path/filepath" | ||
|
||
"github.com/cosmos/cosmos-sdk/server/types" | ||
dbm "github.com/tendermint/tm-db" | ||
) | ||
|
||
func OpenDB(_ types.AppOptions, home string, backendType dbm.BackendType) (dbm.DB, error) { | ||
dataDir := filepath.Join(home, "data") | ||
return dbm.NewDB("application", backendType, dataDir) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
//go:build rocksdb | ||
// +build rocksdb | ||
|
||
// Copyright 2023 Kava Labs, Inc. | ||
// Copyright 2023 Cronos Labs, Inc. | ||
// | ||
// Derived from https://github.com/crypto-org-chain/cronos@496ce7e | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package opendb | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"os" | ||
"path/filepath" | ||
"runtime" | ||
"strings" | ||
|
||
"github.com/spf13/cast" | ||
|
||
"github.com/cosmos/cosmos-sdk/server/types" | ||
"github.com/linxGnu/grocksdb" | ||
dbm "github.com/tendermint/tm-db" | ||
) | ||
|
||
const BlockCacheSize = 1 << 30 | ||
|
||
func OpenDB(appOpts types.AppOptions, home string, backendType dbm.BackendType) (dbm.DB, error) { | ||
dataDir := filepath.Join(home, "data") | ||
if backendType == dbm.RocksDBBackend { | ||
return openRocksdb(filepath.Join(dataDir, "application.db"), appOpts) | ||
} | ||
|
||
return dbm.NewDB("application", backendType, dataDir) | ||
} | ||
|
||
func openRocksdb(dir string, appOpts types.AppOptions) (dbm.DB, error) { | ||
dbOpts, cfOpts, err := loadLatestOptions(dir) | ||
if err != nil { | ||
return nil, err | ||
} | ||
// customize rocksdb options | ||
dbOpts = overrideDBOpts(dbOpts, appOpts) | ||
cfOpts = overrideCFOpts(cfOpts, appOpts) | ||
|
||
return newRocksDBWithOptions("application", dir, dbOpts, cfOpts) | ||
} | ||
|
||
// loadLatestOptions try to load options from existing db, returns nil if not exists. | ||
func loadLatestOptions(dir string) (*grocksdb.Options, *grocksdb.Options, error) { | ||
latestOpts, err := grocksdb.LoadLatestOptions(dir, grocksdb.NewDefaultEnv(), true, grocksdb.NewLRUCache(BlockCacheSize)) | ||
if err != nil { | ||
// not found is not an error | ||
if strings.HasPrefix(err.Error(), "NotFound: ") { | ||
return newDefaultOptions(), newDefaultOptions(), nil | ||
} | ||
return nil, nil, err | ||
} | ||
|
||
cfNames := latestOpts.ColumnFamilyNames() | ||
ok := len(cfNames) == 1 && cfNames[0] == "default" | ||
if !ok { | ||
return nil, nil, errors.New("TODO") | ||
} | ||
cfOpts := latestOpts.ColumnFamilyOpts() | ||
|
||
return latestOpts.Options(), &cfOpts[0], nil | ||
} | ||
|
||
// NewRocksdbOptions build options for `application.db`, | ||
// it overrides existing options if provided, otherwise create new one assuming it's a new database. | ||
func overrideDBOpts(dbOpts *grocksdb.Options, appOpts types.AppOptions) *grocksdb.Options { | ||
maxOpenFiles := cast.ToInt(appOpts.Get("max_open_files")) | ||
if maxOpenFiles != 0 { | ||
dbOpts.SetMaxOpenFiles(maxOpenFiles) | ||
} | ||
|
||
return dbOpts | ||
} | ||
|
||
func overrideCFOpts(cfOpts *grocksdb.Options, appOpts types.AppOptions) *grocksdb.Options { | ||
writeBufferSize := cast.ToUint64(appOpts.Get("write_buffer_size")) | ||
if writeBufferSize != 0 { | ||
cfOpts.SetWriteBufferSize(writeBufferSize) | ||
} | ||
|
||
return cfOpts | ||
} | ||
|
||
func newRocksDBWithOptions(name string, dir string, dbOpts, cfOpts *grocksdb.Options) (*dbm.RocksDB, error) { | ||
dbPath := filepath.Join(dir, name+".db") | ||
|
||
// Ensure path exists | ||
if err := os.MkdirAll(dbPath, 0755); err != nil { | ||
return nil, fmt.Errorf("failed to create db path: %w", err) | ||
} | ||
|
||
db, _, err := grocksdb.OpenDbColumnFamilies(dbOpts, dbPath, []string{"default"}, []*grocksdb.Options{cfOpts}) | ||
if err != nil { | ||
return nil, err | ||
} | ||
ro := grocksdb.NewDefaultReadOptions() | ||
wo := grocksdb.NewDefaultWriteOptions() | ||
woSync := grocksdb.NewDefaultWriteOptions() | ||
woSync.SetSync(true) | ||
return dbm.NewRocksDBWithRawDB(db, ro, wo, woSync), nil | ||
} | ||
|
||
func newDefaultOptions() *grocksdb.Options { | ||
// default rocksdb option, good enough for most cases, including heavy workloads. | ||
// 1GB table cache, 512MB write buffer(may use 50% more on heavy workloads). | ||
// compression: snappy as default, need to -lsnappy to enable. | ||
bbto := grocksdb.NewDefaultBlockBasedTableOptions() | ||
bbto.SetBlockCache(grocksdb.NewLRUCache(1 << 30)) | ||
bbto.SetFilterPolicy(grocksdb.NewBloomFilter(10)) | ||
|
||
opts := grocksdb.NewDefaultOptions() | ||
opts.SetBlockBasedTableFactory(bbto) | ||
// SetMaxOpenFiles to 4096 seems to provide a reliable performance boost | ||
opts.SetMaxOpenFiles(4096) | ||
opts.SetCreateIfMissing(true) | ||
opts.IncreaseParallelism(runtime.NumCPU()) | ||
// 1.5GB maximum memory use for writebuffer. | ||
opts.OptimizeLevelStyleCompaction(512 * 1024 * 1024) | ||
|
||
return opts | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters