Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Database backend configuration #4828

Open
wants to merge 6 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/unit_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
RELEASE:
- ${{ startsWith(github.ref, 'refs/tags/') }}
env:
BACKEND: ${{ matrix.BACKEND }}
NANO_BACKEND: ${{ matrix.BACKEND }}
BUILD_TYPE: ${{ matrix.RELEASE && 'RelWithDebInfo' || 'Debug' }}
TEST_USE_ROCKSDB: ${{ matrix.BACKEND == 'rocksdb' && '1' || '0' }}
DEADLINE_SCALE_FACTOR: ${{ matrix.BACKEND == 'rocksdb' && '2' || '1' }}
Expand Down
3 changes: 1 addition & 2 deletions nano/lib/rocksdbconfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

nano::error nano::rocksdb_config::serialize_toml (nano::tomlconfig & toml) const
{
toml.put ("enable", enable, "Whether to use the RocksDB backend for the ledger database.\ntype:bool");
toml.put ("io_threads", io_threads, "Number of threads to use with the background compaction and flushing.\ntype:uint32");
toml.put ("read_cache", read_cache, "Amount of megabytes per table allocated to read cache. Valid range is 1 - 1024. Default is 32.\nCarefully monitor memory usage if non-default values are used\ntype:long");
toml.put ("write_cache", write_cache, "Total amount of megabytes allocated to write cache. Valid range is 1 - 256. Default is 64.\nCarefully monitor memory usage if non-default values are used\ntype:long");
Expand All @@ -14,7 +13,7 @@ nano::error nano::rocksdb_config::serialize_toml (nano::tomlconfig & toml) const

nano::error nano::rocksdb_config::deserialize_toml (nano::tomlconfig & toml)
{
toml.get_optional<bool> ("enable", enable);
toml.get_optional<bool> ("enable", enable); // TODO: This setting can be removed in future versions
toml.get_optional<unsigned> ("io_threads", io_threads);
toml.get_optional<long> ("read_cache", read_cache);
toml.get_optional<long> ("write_cache", write_cache);
Expand Down
11 changes: 9 additions & 2 deletions nano/node/make_store.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,19 @@
#include <nano/store/lmdb/lmdb.hpp>
#include <nano/store/rocksdb/rocksdb.hpp>

std::unique_ptr<nano::store::component> nano::make_store (nano::logger & logger, std::filesystem::path const & path, nano::ledger_constants & constants, bool read_only, bool add_db_postfix, nano::node_config const & node_config)
std::unique_ptr<nano::store::component> nano::make_store (nano::logger & logger, std::filesystem::path const & path, nano::ledger_constants & constants, bool read_only, bool add_db_postfix, nano::node_config node_config)
{
if (node_config.rocksdb_config.enable)
if (node_config.database_backend == nano::database_backend::rocksdb)
{
return std::make_unique<nano::store::rocksdb::component> (logger, add_db_postfix ? path / "rocksdb" : path, constants, node_config.rocksdb_config, read_only);
}
if (node_config.rocksdb_config.enable && node_config.database_backend == nano::database_backend::lmdb)
{
// rocksdb.enable is true in config, but database_backend is set to LMDB in config
logger.warn (nano::log::type::config, "Use of deprecated RocksDb setting detected in config file.\nPlease edit node_config.toml and use the new 'database_backend' to enable RocksDb");
node_config.database_backend = nano::database_backend::rocksdb;
return std::make_unique<nano::store::rocksdb::component> (logger, add_db_postfix ? path / "rocksdb" : path, constants, node_config.rocksdb_config, read_only);
}

return std::make_unique<nano::store::lmdb::component> (logger, add_db_postfix ? path / "data.ldb" : path, constants, node_config.diagnostics_config.txn_tracking, node_config.block_processor_batch_max_time, node_config.lmdb_config, node_config.backup_before_upgrade);
}
2 changes: 1 addition & 1 deletion nano/node/make_store.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,5 @@ class component;

namespace nano
{
std::unique_ptr<nano::store::component> make_store (nano::logger &, std::filesystem::path const & path, nano::ledger_constants & constants, bool read_only = false, bool add_db_postfix = true, nano::node_config const & node_config = nano::node_config{});
std::unique_ptr<nano::store::component> make_store (nano::logger &, std::filesystem::path const & path, nano::ledger_constants & constants, bool read_only = false, bool add_db_postfix = true, nano::node_config node_config = nano::node_config{});
}
58 changes: 58 additions & 0 deletions nano/node/nodeconfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,8 @@ nano::error nano::node_config::deserialize_toml (nano::tomlconfig & toml)
toml.get<bool> ("allow_local_peers", allow_local_peers);
toml.get<unsigned> (signature_checker_threads_key, signature_checker_threads);

database_backend = get_config_backend (toml);

if (toml.has_key ("lmdb"))
{
auto lmdb_config_l (toml.get_required_child ("lmdb"));
Expand Down Expand Up @@ -659,6 +661,62 @@ void nano::node_config::deserialize_address (std::string const & entry_a, std::v
}
}

std::string nano::node_config::serialize_database_backend (nano::database_backend backend) const
{
switch (backend)
{
case nano::database_backend::rocksdb:
return "rocksdb";
case nano::database_backend::lmdb:
return "lmdb";
}
debug_assert (false);
}

std::optional<nano::database_backend> nano::node_config::deserialize_database_backend (std::string backend_str) const
{
if (backend_str == "rocksdb")
return database_backend::rocksdb;
if (backend_str == "lmdb")
return database_backend::lmdb;
return std::nullopt;
}

nano::database_backend nano::node_config::get_config_backend (nano::tomlconfig & toml)
{
if (toml.has_key ("database_backend"))
{
auto backend_str = (toml.get<std::string> ("database_backend"));
auto backend = deserialize_database_backend (backend_str);
if (backend.has_value ())
{
return backend.value ();
}
toml.get_error ().set ("Unknown database_backend type: " + backend_str);
return nano::database_backend::lmdb;
}
// Default to LMDB
return nano::database_backend::lmdb;
}

nano::database_backend nano::node_config::get_default_backend ()
{
auto backend_str = nano::env::get<std::string> ("NANO_BACKEND");

if (backend_str.has_value ())
{
auto backend = deserialize_database_backend (backend_str.value ());
if (backend.has_value ())
{
std::cerr << "Database backend overridden by NANO_BACKEND environment variable: " << *backend_str << std::endl;
return backend.value ();
}

std::cerr << "Unknown database backend in NANO_BACKEND environment variable: " << *backend_str << std::endl;
}
return database_backend::lmdb;
}

nano::account nano::node_config::random_representative () const
{
debug_assert (!preconfigured_representatives.empty ());
Expand Down
11 changes: 11 additions & 0 deletions nano/node/nodeconfig.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ namespace nano
{
class tomlconfig;

enum class database_backend
{
lmdb,
rocksdb
};

/**
* Node configuration
*/
Expand Down Expand Up @@ -133,6 +139,7 @@ class node_config
uint64_t max_pruning_depth{ 0 };
nano::rocksdb_config rocksdb_config;
nano::lmdb_config lmdb_config;
nano::database_backend database_backend{ get_default_backend () };
bool enable_upnp{ true };
std::size_t max_ledger_notifications{ 8 };

Expand All @@ -156,6 +163,10 @@ class node_config
public:
/** Entry is ignored if it cannot be parsed as a valid address:port */
void deserialize_address (std::string const &, std::vector<std::pair<std::string, uint16_t>> &) const;
std::string serialize_database_backend (nano::database_backend) const;
std::optional<nano::database_backend> deserialize_database_backend (std::string backend_str) const;
nano::database_backend get_config_backend (nano::tomlconfig & toml);
nano::database_backend get_default_backend ();

private:
static std::optional<unsigned> env_io_threads ();
Expand Down
4 changes: 2 additions & 2 deletions nano/secure/ledger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1304,7 +1304,7 @@ bool nano::ledger::migrate_lmdb_to_rocksdb (std::filesystem::path const & data_p

// Open rocksdb database
nano::node_config node_config;
node_config.rocksdb_config.enable = true;
node_config.database_backend = database_backend::rocksdb;
auto rocksdb_store = nano::make_store (logger, data_path_a, nano::dev::constants, false, true, node_config);

if (!rocksdb_store->init_error ())
Expand Down Expand Up @@ -1487,7 +1487,7 @@ bool nano::ledger::migrate_lmdb_to_rocksdb (std::filesystem::path const & data_p
}
}

logger.info (nano::log::type::ledger, "Migration completed. Make sure to enable RocksDB in the config file under [node.rocksdb]");
logger.info (nano::log::type::ledger, "Migration completed. Make sure to update [node.database_backend] to 'rocksdb' in config.toml");
logger.info (nano::log::type::ledger, "After confirming correct node operation, the data.ldb file can be deleted if no longer required");
}
else
Expand Down
Loading