Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

Memory-based pruning history size #4114

Merged
merged 8 commits into from
Jan 20, 2017
Merged

Memory-based pruning history size #4114

merged 8 commits into from
Jan 20, 2017

Conversation

rphmeier
Copy link
Contributor

Closes #4090

Might also come with changes to informant + a different default setting (currently 150MB)

@rphmeier rphmeier added A0-pleasereview 🤓 Pull request needs code review. M4-core ⛓ Core client code / Rust. labels Jan 10, 2017
@rphmeier rphmeier requested a review from arkpar January 10, 2017 14:46
// prune all ancient eras until we're below the memory target,
// but have at least the minimum number of states.
loop {
if state.journal_db().mem_used() <= self.config.history_mem { break }
Copy link
Contributor Author

Choose a reason for hiding this comment

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

slight concern here about the time taken perform this check potentially multiple times per imported block -- an optimization might be done via incremental bookkeeping using the sizes of key-value pairs inserted and deleted into the pruning overlay rather than sweeping the whole overlay each time.

@rphmeier rphmeier added A3-inprogress ⏳ Pull request is in progress. No review needed at this stage. and removed A0-pleasereview 🤓 Pull request needs code review. labels Jan 10, 2017
@rphmeier
Copy link
Contributor Author

Hm, apparently earliest_era isn't actually updated when marking states canonical, leading to an infinite loop...

@@ -170,7 +171,20 @@ impl SnapshotCommand {
execute_upgrades(&self.dirs.base, &db_dirs, algorithm, self.compaction.compaction_profile(db_dirs.db_root_path().as_path()))?;

// prepare client config
let client_config = to_client_config(&self.cache_config, Mode::Active, tracing, fat_db, self.compaction, self.wal, VMType::default(), "".into(), algorithm, self.pruning_history, true);
let client_config = to_client_config(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

the fact that this stuff is duplicated so much is practically a crime :)
Since basically every subcommand needs to initialize a client (and initializing a client needs, at a minimum, some of these parameters), the commands themselves should just take a client config rather than rebuilding it each and every time.

@rphmeier rphmeier added A0-pleasereview 🤓 Pull request needs code review. and removed A3-inprogress ⏳ Pull request is in progress. No review needed at this stage. labels Jan 12, 2017
@coveralls
Copy link

Coverage Status

Changes Unknown when pulling cc69ab5 on memory-pruning into ** on master**.

@rphmeier
Copy link
Contributor Author

rphmeier commented Jan 13, 2017

This should help with mitigating forks on the testnet: with the default setting of --pruning-memory 150, about 1200 states are stored at the head of the chain.

--pruning-memory MB The ideal amount of memory in megabytes to use to store
recent states. As many states as possible will be kept
within this limit, and at least --pruning-history states
will always be kept. (default: {flag_pruning_memory})
Copy link
Collaborator

Choose a reason for hiding this comment

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

2 lines above should be aligned with spaces

@arkpar arkpar added A8-looksgood 🦄 Pull request is reviewed well. and removed A0-pleasereview 🤓 Pull request needs code review. labels Jan 18, 2017
@@ -578,9 +564,49 @@ impl Client {
self.db.read().write_buffered(batch);
chain.commit();
self.update_last_hashes(&parent, hash);

if let Err(e) = self.prune_ancient(state, &chain) {
Copy link
Contributor

@gavofyork gavofyork Jan 18, 2017

Choose a reason for hiding this comment

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

just wondering if this breaks an implicit precondition that the ancient block should be marked canon before the new block is committed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is still analogous to the prior behavior in the case of 1 entry being pruned: journal_under was previously called before mark_canonical. Nothing in the JournalDB interface (or our implementations) should prohibit "runs" of either call without alternation.

@rphmeier
Copy link
Contributor Author

My main concern about this PR is that it changes the memory usage calculations for the journal DB substantially (they now tend to be 1.5-2x lower than previously) in order to keep them fast enough to call multiple times per-block.

@arkpar
Copy link
Collaborator

arkpar commented Jan 18, 2017

@rphmeier Is that because of additional check here: https://github.com/ethcore/parity/pull/4114/files#diff-698ad0b84c222f83a6207ea3c6d8bc07R170?
Maybe change emplace to return bool instead?

@rphmeier
Copy link
Contributor Author

@arkpar that check is because values may exist in the overlay multiple times, but we only want to count its size once. the lower calculated memory usage is because we no longer use heap_size_of_children on everything, just incrementally keep track of state items' sizes, so we're essentially ignoring HashMap overhead.

@rphmeier rphmeier added the B7-releasenotes 📜 Changes should be mentioned in the release notes of the next minor version release. label Jan 19, 2017
@rphmeier
Copy link
Contributor Author

re: memory calculation concerns.

I've added a journal_size function to JournalDB which reports the amount of memory journalled state objects are currently taking up. The dynamic pruning will use this, and mem_used for fast pruning has been restored to its original slow state. This means that the informant will always print something higher than --pruning-memory in the db section, but this was already the case since the field includes the state cache size as well.

@gavofyork gavofyork merged commit 203fd8a into master Jan 20, 2017
@gavofyork gavofyork deleted the memory-pruning branch January 20, 2017 12:25
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
A8-looksgood 🦄 Pull request is reviewed well. B7-releasenotes 📜 Changes should be mentioned in the release notes of the next minor version release. M4-core ⛓ Core client code / Rust.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants