-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
feat(pruner): respect batch size per run #4246
Conversation
Codecov Report
... and 13 files with indirect coverage changes
Flags with carried forward coverage won't be shown. Click here to find out more.
|
8d90ebb
to
d838d1c
Compare
d838d1c
to
adffcf6
Compare
c26026c
to
128a293
Compare
128a293
to
54a67f6
Compare
/// Returns number of rows pruned. | ||
pub fn prune_table_with_range_in_batches<T: Table>( | ||
/// Returns number of total unique keys and total rows pruned pruned. | ||
pub fn prune_table_with_range<T: Table>( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: doc what the bool represents
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
logic seems good, lets test this bad boy on mainnet
a560441
to
4939ab9
Compare
This reverts commit df14e1e.
45d801b
to
bedb5a4
Compare
6511021
to
1ac798b
Compare
bdf64ed
to
b941ed4
Compare
let prune_mode_block = self | ||
.modes | ||
.contract_logs_filter | ||
.lowest_block_with_distance(tip_block_number, pruned_block)? | ||
.lowest_block_with_distance(tip_block_number, initial_last_pruned_block)? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is it correct? shouldn't it be last_pruned_block
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should be correct, this argument works as a lower bound.
if we set it to last_pruned_block
something of the kind would happen:
example:
(distance(200), addrA)
- contract log pruner goes until distance(128).
last_pruned_block
would be the block from distance(128)
Which would mean that we'd never go through the blocks between distance(200) -> distance(128)
for the tip
of this particular run. However, for future runs with higher tips, they should get checked and cleaned-up
d4dcc1f
to
407bdcc
Compare
Problem
Previously batches inside the pruner were only used to print the progress, but the pruning itself was done in one go: one large MDBX transaction that deleted the data in tables according to the provided pruning modes.
This approach had one big downside: MDBX can't do a good job of deleting large chunks of data. This is due to how MDBX deletions work: pages previously occupied by the data aren't just deleted but instead placed inside a "freelist" data structure, which consequent data insertions use to minimize the allocations of new pages. The problem arises when we delete a lot of data in one go: the freelist grows too much, and to insert e.g. a new large entry into
Transactions
table, the MDBX needs to scan the freelist for overflow pages first. It might take a lot of time, and we noticed it with Optimism transactions that took 30 overflow pages to insert.Solution
Delete only small portions of data in one pruner run, allowing the data from new blocks to fill the gaps in database to prevent the freelist from growing too much and causing the aforementioned issue. It works by re-using the
BatchSizes
struct, but instead using it to limit the amount of rows to delete per prune part.It means that:
TxSenders
table (which is the only table that's populated during the pipeline sync even if the prune mode says to prune it) up to the specified block, the pruner will need to run a certain amount of times, allowing the live sync to insert new data between pruner runs. If we run the pruner every 5 blocks, prune 1000 transaction senders per run and have 2 billion transaction senders to prune, it will take2_000_000_000 transaction senders / 1000 transaction senders per run = 2_000_000 pruner runs
and2_000_000 pruner runs / (5 blocks * 12 seconds) = 9.2 hours
.