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

Improve chainbase mapped and heap behavior #1691

Merged
merged 23 commits into from
Oct 5, 2023
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
a098946
Use Chainbase's branch with `mapped` mode updates.
greg7mdp Sep 28, 2023
121b0f7
Update chainbase to branch tip.
greg7mdp Sep 28, 2023
2914f46
Use `mapped_shared` mode for chainbase when loading snapshot.
greg7mdp Sep 28, 2023
63e6bef
Try making the new mode not the default one (renaming new mode `mappe…
greg7mdp Sep 29, 2023
73a6d22
Load snapshot in `mapped_shared` in leap-util, and revert to new mode…
greg7mdp Sep 29, 2023
7da7862
Merge branch 'main' of github.com:AntelopeIO/leap into gh_1650
greg7mdp Sep 29, 2023
8140958
Update to appbase branch tip.
greg7mdp Sep 29, 2023
418a570
Update chainbase to tip:
greg7mdp Sep 30, 2023
811192f
Update chainbase to tip.
greg7mdp Oct 2, 2023
797f045
Update appbase to branch tip.
greg7mdp Oct 2, 2023
ca9b6a9
If `mapped` mode was requested, revert to it after loading snapshot.
greg7mdp Oct 2, 2023
5618bd1
Update chainbase to branch tip.
greg7mdp Oct 3, 2023
bb86cf0
Call chainbase API to give the opportunity to flush some dirty pages.
greg7mdp Oct 3, 2023
fc421a9
Address PR comments (log info message in controller, naming)
greg7mdp Oct 3, 2023
43006e2
Make the new mode non-default; rename it `mapped_private`.
greg7mdp Oct 3, 2023
b02fa00
Call `check_memory_and_flush_if_needed()` only in write window as Mat…
greg7mdp Oct 3, 2023
6f0782d
Add snapshot load time to info log
greg7mdp Oct 4, 2023
958bc01
Merge branch 'main' of github.com:AntelopeIO/leap into gh_1650
greg7mdp Oct 4, 2023
5c9ebe7
Address PR comment (remove unneeded line)
greg7mdp Oct 4, 2023
eefda26
Add `mapped_private` description to `--help` and docs.
greg7mdp Oct 4, 2023
e023358
Merge branch 'main' of github.com:AntelopeIO/leap into gh_1650
greg7mdp Oct 4, 2023
f427935
Update to chainbase tip (`main` branch)
greg7mdp Oct 5, 2023
d8fb38c
Merge branch 'main' of github.com:AntelopeIO/leap into gh_1650
greg7mdp Oct 5, 2023
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
20 changes: 14 additions & 6 deletions libraries/chain/controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@

#include <new>
#include <shared_mutex>
#include <utility>

namespace eosio { namespace chain {

Expand Down Expand Up @@ -605,7 +606,9 @@ struct controller_impl {
}
ilog( "Snapshot loaded, lib: ${lib}", ("lib", head->block_num) );

init(check_shutdown);
init(std::move(check_shutdown));
if (conf.revert_to_private_mode)
db.revert_to_private_mode();
ilog( "Finished initialization from snapshot" );
} catch (boost::interprocess::bad_alloc& e) {
elog( "Failed initialization from snapshot - db storage not configured to have enough storage for the provided snapshot, please increase and retry snapshot" );
Expand All @@ -621,7 +624,7 @@ struct controller_impl {
("genesis_chain_id", genesis_chain_id)("controller_chain_id", chain_id)
);

this->shutdown = shutdown;
this->shutdown = std::move(shutdown);
if( fork_db.head() ) {
if( read_mode == db_read_mode::IRREVERSIBLE && fork_db.head()->id != fork_db.root()->id ) {
fork_db.rollback_head_to_root();
Expand All @@ -643,14 +646,14 @@ struct controller_impl {
} else {
blog.reset( genesis, head->block );
}
init(check_shutdown);
init(std::move(check_shutdown));
}

void startup(std::function<void()> shutdown, std::function<bool()> check_shutdown) {
EOS_ASSERT( db.revision() >= 1, database_exception, "This version of controller::startup does not work with a fresh state database." );
EOS_ASSERT( fork_db.head(), fork_database_exception, "No existing fork database despite existing chain state. Replay required." );

this->shutdown = shutdown;
this->shutdown = std::move(shutdown);
uint32_t lib_num = fork_db.root()->block_num;
auto first_block_num = blog.first_block_num();
if( auto blog_head = blog.head() ) {
Expand All @@ -673,7 +676,7 @@ struct controller_impl {
}
head = fork_db.head();

init(check_shutdown);
init(std::move(check_shutdown));
}


Expand Down Expand Up @@ -3468,9 +3471,14 @@ void controller::validate_tapos( const transaction& trx )const { try {
} FC_CAPTURE_AND_RETHROW() }

void controller::validate_db_available_size() const {
const auto free = db().get_segment_manager()->get_free_memory();
const auto free = db().get_free_memory();
const auto guard = my->conf.state_guard_size;
EOS_ASSERT(free >= guard, database_guard_exception, "database free: ${f}, guard size: ${g}", ("f", free)("g",guard));

// give a change to chainbase to write some pages to disk if memory becomes scarce.
if (auto flushed_pages = mutable_db().check_memory_and_flush_if_needed()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this call is only safe during the write window (at least, if it's actually clearing dirty bits). Are we sure validate_db_available_size() is only called during the write window? This one I'm not sure about due to ROtrx,

transaction_trace_ptr controller::push_transaction( const transaction_metadata_ptr& trx,
fc::time_point block_deadline, fc::microseconds max_transaction_time,
uint32_t billed_cpu_time_us, bool explicit_billed_cpu_time,
int64_t subjective_cpu_bill_us ) {
validate_db_available_size();
EOS_ASSERT( get_read_mode() != db_read_mode::IRREVERSIBLE, transaction_type_exception, "push transaction not allowed in irreversible mode" );
EOS_ASSERT( trx && !trx->implicit() && !trx->scheduled(), transaction_type_exception, "Implicit/Scheduled transaction not allowed" );
return my->push_transaction(trx, block_deadline, max_transaction_time, billed_cpu_time_us, explicit_billed_cpu_time, subjective_cpu_bill_us );
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. This is called from multiple read-only threads for read-only trx execution.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

ilog("CHAINBASE: flushed ${p} pages to disk to decrease memory pressure", ("p", flushed_pages));
}
}

bool controller::is_protocol_feature_activated( const digest_type& feature_digest )const {
Expand Down
1 change: 1 addition & 0 deletions libraries/chain/include/eosio/chain/controller.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ namespace eosio { namespace chain {
bool disable_replay_opts = false;
bool contracts_console = false;
bool allow_ram_billing_in_notify = false;
bool revert_to_private_mode = false;
uint32_t maximum_variable_signature_length = chain::config::default_max_variable_signature_length;
bool disable_all_subjective_mitigations = false; //< for developer & testing purposes, can be configured using `disable-all-subjective-mitigations` when `EOSIO_DEVELOPER` build option is provided
uint32_t terminate_at_block = 0;
Expand Down
7 changes: 7 additions & 0 deletions plugins/chain_plugin/chain_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -934,6 +934,13 @@ void chain_plugin_impl::plugin_initialize(const variables_map& options) {

chain_config->db_map_mode = options.at("database-map-mode").as<pinnable_mapped_file::map_mode>();

// when loading a snapshot, all the state will be modified, so temporarily use the `mapped` mode instead
// of `mapped_private` to lower memory requirements.
if (snapshot_path && chain_config->db_map_mode == pinnable_mapped_file::mapped_private) {
chain_config->db_map_mode = pinnable_mapped_file::mapped;
chain_config->revert_to_private_mode = true; // revert to `mapped_private` mode after loading snapshot.
}

#ifdef EOSIO_EOS_VM_OC_RUNTIME_ENABLED
if( options.count("eos-vm-oc-cache-size-mb") )
chain_config->eosvmoc_config.cache_size = options.at( "eos-vm-oc-cache-size-mb" ).as<uint64_t>() * 1024u * 1024u;
Expand Down
2 changes: 2 additions & 0 deletions programs/leap-util/actions/snapshot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ int snapshot_actions::run_subcommand() {
cfg.state_size = opt->db_size * 1024 * 1024;
cfg.state_guard_size = opt->guard_size * 1024 * 1024;
cfg.eosvmoc_tierup = wasm_interface::vm_oc_enable::oc_none; // wasm not used, no use to fire up oc

cfg.db_map_mode = pinnable_mapped_file::map_mode::mapped;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think need this line any more

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right, that's the default. removed.

protocol_feature_set pfs = initialize_protocol_features( std::filesystem::path("protocol_features"), false );

try {
Expand Down