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

Cleanup blocks from db (incl. forked blocks) #2815

Merged
merged 4 commits into from
May 13, 2019

Conversation

miketang84
Copy link
Contributor

fix: try to fix issue #2585 by adding block cleanup from db directly.

@@ -1065,6 +1065,49 @@ impl Chain {
count, tail.height
);

// Remove short live fork blocks
// Get all block headers in db
let all_block_headers = self.store.all_block_headers()?;
Copy link
Contributor

Choose a reason for hiding this comment

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

You'll want to iterate over all blocks, not block headers. We never compact/delete the block headers, so using your approach would end up iterating over 100s of thousands of headers. Blocks are compacted frequently, which means we never have more than a few weeks worth of them. Just iterate over each block in the store, check is_on_current_chain and check block.header.height >= tail.height. If either of those is false, call delete_block.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hi, updated with new algorithm u advised :)

Copy link
Member

@antiochp antiochp left a comment

Choose a reason for hiding this comment

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

Going to test this locally - but looks good.

@@ -378,6 +378,13 @@ impl<'a> Batch<'a> {
db: self.db.child()?,
})
}

/// An iterator to all lived block now
pub fn iter_lived_blocks(&self) -> Result<SerIterator<Block>, Error> {
Copy link
Member

Choose a reason for hiding this comment

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

Maybe rename this to blocks_iter() for consistency with difficulty_iter() (and others)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok.

Err(NotFoundErr(_)) => break,
Err(e) => return Err(From::from(e)),
// Remove old blocks and short live fork blocks
// here b is a lived block
Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure what you mean by "lived" block - maybe reword these comments?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok.

Err(e) => return Err(From::from(e)),
// Remove old blocks and short live fork blocks
// here b is a lived block
let _ = batch.iter_lived_blocks()?.map(|(_, b)| {
Copy link
Member

Choose a reason for hiding this comment

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

This can be simplified to -

for (_, b) in batch.iter_lived_blocks()? {
    ...
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok.

@antiochp
Copy link
Member

Looks like lmdb is locking up internally with this change - our "batch" is very susceptible to deadlocking with multiple accesses.
I'm looking to see if there are any obvious culprits here.

@miketang84
Copy link
Contributor Author

Looks like lmdb is locking up internally with this change - our "batch" is very susceptible to deadlocking with multiple accesses.
I'm looking to see if there are any obvious culprits here.

Wow, this is my first attempt to contribute to grin, so lack experiences on it. :(

@miketang84
Copy link
Contributor Author

Or should I use store_instance.iter() rather than batch.iter() in exported iterator in chain/src/store.rs?

2. comments and iterator calling optimiztions.

Signed-off-by: Mike Tang <[email protected]>
@antiochp
Copy link
Member

Ha - It's the call to is_on_current_chain().
Turns out we cannot actually call this inside the iterator (as it tries to get a lock on the db but the batch already has a lock on it).
I'll take another pass later today and see if we can rework this to use the existing batch.

@miketang84
Copy link
Contributor Author

In my opinion, maybe we don't need batch lock in the procedure of iterating over blocks in db, this is not necessary for the whole block cleanup, only necessary when delete one block. So, we can add an iterator to ChainStore implementation, rather than Batch.

@antiochp
Copy link
Member

I think we actually got the logic wrong here.

Now that we are iterating over all blocks in the db, all we really care about is cleaning up blocks older than the threshold.

So we do not need to actually check for is_on_current_chain() - if its older than tail.height we simply delete it, whether on current chain or not.

And this should resolve the deadlocking issue as well I think.

@miketang84
Copy link
Contributor Author

The height of a fork block MUST be smaller than tail.height? Surely?

@antiochp
Copy link
Member

The height of a fork block MUST be smaller than tail.height? Surely?

Yes - we want to delete block older (i.e. lower height) than tail.height

…er just by removing it.

Because "we want to delete block older (i.e. lower height) than tail.height".

Signed-off-by: Mike Tang <[email protected]>
Copy link
Member

@antiochp antiochp left a comment

Choose a reason for hiding this comment

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

Simpler, more effective and less code. 👍

@antiochp antiochp merged commit 9ac4143 into mimblewimble:master May 13, 2019
@antiochp antiochp added this to the 1.1.0 milestone Jun 5, 2019
@antiochp antiochp added the release notes To be included in release notes (of relevant milestone). label Jun 5, 2019
@antiochp antiochp changed the title fix: try to fix issue #2585 by adding block cleanup from db directly. Cleanup blocks from db (incl. forked blocks) Jun 5, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
release notes To be included in release notes (of relevant milestone).
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants