chore(pruner): remove deletion limit per block, make it per run (#9446)

This commit is contained in:
Alexey Shekhirin
2024-07-11 21:16:30 +01:00
committed by GitHub
parent 95bde32cdf
commit 805673c656
11 changed files with 35 additions and 79 deletions

View File

@ -56,7 +56,7 @@ pub static MAINNET: Lazy<Arc<ChainSpec>> = Lazy::new(|| {
b256!("649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5"), b256!("649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5"),
)), )),
base_fee_params: BaseFeeParamsKind::Constant(BaseFeeParams::ethereum()), base_fee_params: BaseFeeParamsKind::Constant(BaseFeeParams::ethereum()),
prune_delete_limit: 3500, prune_delete_limit: 20000,
} }
.into() .into()
}); });
@ -78,7 +78,7 @@ pub static SEPOLIA: Lazy<Arc<ChainSpec>> = Lazy::new(|| {
b256!("649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5"), b256!("649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5"),
)), )),
base_fee_params: BaseFeeParamsKind::Constant(BaseFeeParams::ethereum()), base_fee_params: BaseFeeParamsKind::Constant(BaseFeeParams::ethereum()),
prune_delete_limit: 1700, prune_delete_limit: 10000,
} }
.into() .into()
}); });
@ -98,7 +98,7 @@ pub static HOLESKY: Lazy<Arc<ChainSpec>> = Lazy::new(|| {
b256!("649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5"), b256!("649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5"),
)), )),
base_fee_params: BaseFeeParamsKind::Constant(BaseFeeParams::ethereum()), base_fee_params: BaseFeeParamsKind::Constant(BaseFeeParams::ethereum()),
prune_delete_limit: 1700, prune_delete_limit: 10000,
} }
.into() .into()
}); });
@ -143,7 +143,7 @@ pub static OP_MAINNET: Lazy<Arc<ChainSpec>> = Lazy::new(|| {
] ]
.into(), .into(),
), ),
prune_delete_limit: 1700, prune_delete_limit: 10000,
..Default::default() ..Default::default()
} }
.into() .into()
@ -168,7 +168,7 @@ pub static OP_SEPOLIA: Lazy<Arc<ChainSpec>> = Lazy::new(|| {
] ]
.into(), .into(),
), ),
prune_delete_limit: 1700, prune_delete_limit: 10000,
..Default::default() ..Default::default()
} }
.into() .into()
@ -193,7 +193,7 @@ pub static BASE_SEPOLIA: Lazy<Arc<ChainSpec>> = Lazy::new(|| {
] ]
.into(), .into(),
), ),
prune_delete_limit: 1700, prune_delete_limit: 10000,
..Default::default() ..Default::default()
} }
.into() .into()
@ -218,7 +218,7 @@ pub static BASE_MAINNET: Lazy<Arc<ChainSpec>> = Lazy::new(|| {
] ]
.into(), .into(),
), ),
prune_delete_limit: 1700, prune_delete_limit: 10000,
..Default::default() ..Default::default()
} }
.into() .into()
@ -300,9 +300,7 @@ pub struct ChainSpec {
/// The parameters that configure how a block's base fee is computed /// The parameters that configure how a block's base fee is computed
pub base_fee_params: BaseFeeParamsKind, pub base_fee_params: BaseFeeParamsKind,
/// The delete limit for pruner, per block. In the actual pruner run it will be multiplied by /// The delete limit for pruner, per run.
/// the amount of blocks between pruner runs to account for the difference in amount of new
/// data coming in.
pub prune_delete_limit: usize, pub prune_delete_limit: usize,
} }

View File

@ -30,7 +30,7 @@ impl PruneCommand {
info!(target: "reth::cli", ?prune_tip, ?prune_config, "Pruning data from database..."); info!(target: "reth::cli", ?prune_tip, ?prune_config, "Pruning data from database...");
// Run the pruner according to the configuration, and don't enforce any limits on it // Run the pruner according to the configuration, and don't enforce any limits on it
let mut pruner = PrunerBuilder::new(prune_config) let mut pruner = PrunerBuilder::new(prune_config)
.delete_limit_per_block(usize::MAX) .delete_limit(usize::MAX)
.build_with_provider_factory(provider_factory); .build_with_provider_factory(provider_factory);
pruner.run(prune_tip)?; pruner.run(prune_tip)?;

View File

@ -391,10 +391,13 @@ where
// Setup blockchain tree // Setup blockchain tree
let externals = TreeExternals::new(provider_factory.clone(), consensus, executor_factory); let externals = TreeExternals::new(provider_factory.clone(), consensus, executor_factory);
let config = BlockchainTreeConfig::new(1, 2, 3, 2);
let tree = Arc::new(ShareableBlockchainTree::new( let tree = Arc::new(ShareableBlockchainTree::new(
BlockchainTree::new(externals, config, PruneModes::default()) BlockchainTree::new(
.expect("failed to create tree"), externals,
BlockchainTreeConfig::new(1, 2, 3, 2),
PruneModes::default(),
)
.expect("failed to create tree"),
)); ));
let latest = self.base_config.chain_spec.genesis_header().seal_slow(); let latest = self.base_config.chain_spec.genesis_header().seal_slow();
let blockchain_provider = let blockchain_provider =
@ -405,7 +408,6 @@ where
vec![], vec![],
5, 5,
self.base_config.chain_spec.prune_delete_limit, self.base_config.chain_spec.prune_delete_limit,
config.max_reorg_depth() as usize,
None, None,
watch::channel(FinishedExExHeight::NoExExs).1, watch::channel(FinishedExExHeight::NoExExs).1,
); );

View File

@ -314,7 +314,6 @@ mod tests {
vec![], vec![],
5, 5,
0, 0,
5,
None, None,
finished_exex_height_rx, finished_exex_height_rx,
); );

View File

@ -329,7 +329,7 @@ impl<R> LaunchContextWith<Attached<WithConfigs, R>> {
/// Returns an initialized [`PrunerBuilder`] based on the configured [`PruneConfig`] /// Returns an initialized [`PrunerBuilder`] based on the configured [`PruneConfig`]
pub fn pruner_builder(&self) -> PrunerBuilder { pub fn pruner_builder(&self) -> PrunerBuilder {
PrunerBuilder::new(self.prune_config().unwrap_or_default()) PrunerBuilder::new(self.prune_config().unwrap_or_default())
.delete_limit_per_block(self.chain_spec().prune_delete_limit) .delete_limit(self.chain_spec().prune_delete_limit)
.timeout(PrunerBuilder::DEFAULT_TIMEOUT) .timeout(PrunerBuilder::DEFAULT_TIMEOUT)
} }

View File

@ -231,14 +231,11 @@ where
let initial_target = ctx.node_config().debug.tip; let initial_target = ctx.node_config().debug.tip;
let mut pruner_builder = ctx let mut pruner_builder = ctx.pruner_builder();
.pruner_builder()
.prune_max_blocks_per_run(ctx.tree_config().max_reorg_depth() as usize);
if let Some(exex_manager_handle) = &exex_manager_handle { if let Some(exex_manager_handle) = &exex_manager_handle {
pruner_builder = pruner_builder =
pruner_builder.finished_exex_height(exex_manager_handle.finished_height()); pruner_builder.finished_exex_height(exex_manager_handle.finished_height());
} }
let pruner = pruner_builder.build_with_provider_factory(ctx.provider_factory().clone()); let pruner = pruner_builder.build_with_provider_factory(ctx.provider_factory().clone());
let pruner_events = pruner.events(); let pruner_events = pruner.events();

View File

@ -15,12 +15,8 @@ pub struct PrunerBuilder {
block_interval: usize, block_interval: usize,
/// Pruning configuration for every part of the data that can be pruned. /// Pruning configuration for every part of the data that can be pruned.
segments: PruneModes, segments: PruneModes,
/// The maximum number of blocks that can be pruned per run. /// The delete limit for pruner, per run.
prune_max_blocks_per_run: usize, delete_limit: usize,
/// The delete limit for pruner, per block. In the actual pruner run it will be multiplied by
/// the amount of blocks between pruner runs to account for the difference in amount of new
/// data coming in.
delete_limit_per_block: usize,
/// Time a pruner job can run before timing out. /// Time a pruner job can run before timing out.
timeout: Option<Duration>, timeout: Option<Duration>,
/// The finished height of all `ExEx`'s. /// The finished height of all `ExEx`'s.
@ -50,15 +46,9 @@ impl PrunerBuilder {
self self
} }
/// Sets the number of blocks that can be re-orged. /// Sets the delete limit for pruner, per run.
pub const fn prune_max_blocks_per_run(mut self, prune_max_blocks_per_run: usize) -> Self { pub const fn delete_limit(mut self, prune_delete_limit: usize) -> Self {
self.prune_max_blocks_per_run = prune_max_blocks_per_run; self.delete_limit = prune_delete_limit;
self
}
/// Sets the delete limit for pruner, per block.
pub const fn delete_limit_per_block(mut self, delete_limit_per_block: usize) -> Self {
self.delete_limit_per_block = delete_limit_per_block;
self self
} }
@ -91,8 +81,7 @@ impl PrunerBuilder {
provider_factory, provider_factory,
segments.into_vec(), segments.into_vec(),
self.block_interval, self.block_interval,
self.delete_limit_per_block, self.delete_limit,
self.prune_max_blocks_per_run,
self.timeout, self.timeout,
self.finished_exex_height, self.finished_exex_height,
) )
@ -105,8 +94,7 @@ impl PrunerBuilder {
Pruner::<_, ()>::new( Pruner::<_, ()>::new(
segments.into_vec(), segments.into_vec(),
self.block_interval, self.block_interval,
self.delete_limit_per_block, self.delete_limit,
self.prune_max_blocks_per_run,
self.timeout, self.timeout,
self.finished_exex_height, self.finished_exex_height,
) )
@ -118,8 +106,7 @@ impl Default for PrunerBuilder {
Self { Self {
block_interval: 5, block_interval: 5,
segments: PruneModes::none(), segments: PruneModes::none(),
prune_max_blocks_per_run: 64, delete_limit: MAINNET.prune_delete_limit,
delete_limit_per_block: MAINNET.prune_delete_limit,
timeout: None, timeout: None,
finished_exex_height: watch::channel(FinishedExExHeight::NoExExs).1, finished_exex_height: watch::channel(FinishedExExHeight::NoExExs).1,
} }

View File

@ -37,11 +37,8 @@ pub struct Pruner<DB, PF> {
/// number is updated with the tip block number the pruner was called with. It's used in /// number is updated with the tip block number the pruner was called with. It's used in
/// conjunction with `min_block_interval` to determine when the pruning needs to be initiated. /// conjunction with `min_block_interval` to determine when the pruning needs to be initiated.
previous_tip_block_number: Option<BlockNumber>, previous_tip_block_number: Option<BlockNumber>,
/// Maximum total entries to prune (delete from database) per block. /// Maximum total entries to prune (delete from database) per run.
delete_limit_per_block: usize, delete_limit: usize,
/// Maximum number of blocks to be pruned per run, as an additional restriction to
/// `previous_tip_block_number`.
prune_max_blocks_per_run: usize,
/// Maximum time for a one pruner run. /// Maximum time for a one pruner run.
timeout: Option<Duration>, timeout: Option<Duration>,
/// The finished height of all `ExEx`'s. /// The finished height of all `ExEx`'s.
@ -56,8 +53,7 @@ impl<DB> Pruner<DB, ()> {
pub fn new( pub fn new(
segments: Vec<Box<dyn Segment<DB>>>, segments: Vec<Box<dyn Segment<DB>>>,
min_block_interval: usize, min_block_interval: usize,
delete_limit_per_block: usize, delete_limit: usize,
prune_max_blocks_per_run: usize,
timeout: Option<Duration>, timeout: Option<Duration>,
finished_exex_height: watch::Receiver<FinishedExExHeight>, finished_exex_height: watch::Receiver<FinishedExExHeight>,
) -> Self { ) -> Self {
@ -66,8 +62,7 @@ impl<DB> Pruner<DB, ()> {
segments, segments,
min_block_interval, min_block_interval,
previous_tip_block_number: None, previous_tip_block_number: None,
delete_limit_per_block, delete_limit,
prune_max_blocks_per_run,
timeout, timeout,
finished_exex_height, finished_exex_height,
metrics: Metrics::default(), metrics: Metrics::default(),
@ -82,8 +77,7 @@ impl<DB: Database> Pruner<DB, ProviderFactory<DB>> {
provider_factory: ProviderFactory<DB>, provider_factory: ProviderFactory<DB>,
segments: Vec<Box<dyn Segment<DB>>>, segments: Vec<Box<dyn Segment<DB>>>,
min_block_interval: usize, min_block_interval: usize,
delete_limit_per_block: usize, delete_limit: usize,
prune_max_blocks_per_run: usize,
timeout: Option<Duration>, timeout: Option<Duration>,
finished_exex_height: watch::Receiver<FinishedExExHeight>, finished_exex_height: watch::Receiver<FinishedExExHeight>,
) -> Self { ) -> Self {
@ -92,8 +86,7 @@ impl<DB: Database> Pruner<DB, ProviderFactory<DB>> {
segments, segments,
min_block_interval, min_block_interval,
previous_tip_block_number: None, previous_tip_block_number: None,
delete_limit_per_block, delete_limit,
prune_max_blocks_per_run,
timeout, timeout,
finished_exex_height, finished_exex_height,
metrics: Metrics::default(), metrics: Metrics::default(),
@ -130,25 +123,7 @@ impl<DB: Database, S> Pruner<DB, S> {
debug!(target: "pruner", %tip_block_number, "Pruner started"); debug!(target: "pruner", %tip_block_number, "Pruner started");
let start = Instant::now(); let start = Instant::now();
// Multiply `self.delete_limit` (number of rows to delete per block) by number of blocks let mut limiter = PruneLimiter::default().set_deleted_entries_limit(self.delete_limit);
// since last pruner run. `self.previous_tip_block_number` is close to
// `tip_block_number`, usually within `self.block_interval` blocks, so
// `delete_limit` will not be too high. If it's too high, we additionally limit it by
// `self.prune_max_blocks_per_run`.
//
// Also see docs for `self.previous_tip_block_number`.
let blocks_since_last_run = self
.previous_tip_block_number
.map_or(1, |previous_tip_block_number| {
// Saturating subtraction is needed for the case when the chain was reverted,
// meaning current block number might be less than the previous tip
// block number.
tip_block_number.saturating_sub(previous_tip_block_number) as usize
})
.min(self.prune_max_blocks_per_run);
let mut limiter = PruneLimiter::default()
.set_deleted_entries_limit(self.delete_limit_per_block * blocks_since_last_run);
if let Some(timeout) = self.timeout { if let Some(timeout) = self.timeout {
limiter = limiter.set_time_limit(timeout); limiter = limiter.set_time_limit(timeout);
}; };
@ -411,7 +386,6 @@ mod tests {
vec![], vec![],
5, 5,
0, 0,
5,
None, None,
finished_exex_height_rx, finished_exex_height_rx,
); );

View File

@ -7,7 +7,7 @@ use std::{
/// or the time it can run. /// or the time it can run.
#[derive(Debug, Clone, Default)] #[derive(Debug, Clone, Default)]
pub struct PruneLimiter { pub struct PruneLimiter {
/// Maximum entries (rows in the database) to delete from the database per block. /// Maximum entries (rows in the database) to delete from the database per run.
deleted_entries_limit: Option<PruneDeletedEntriesLimit>, deleted_entries_limit: Option<PruneDeletedEntriesLimit>,
/// Maximum duration of one prune run. /// Maximum duration of one prune run.
time_limit: Option<PruneTimeLimit>, time_limit: Option<PruneTimeLimit>,

View File

@ -256,7 +256,7 @@ where
// Run the pruner so we don't potentially end up with higher height in the database vs // Run the pruner so we don't potentially end up with higher height in the database vs
// static files during a pipeline unwind // static files during a pipeline unwind
let mut pruner = PrunerBuilder::new(Default::default()) let mut pruner = PrunerBuilder::new(Default::default())
.delete_limit_per_block(usize::MAX) .delete_limit(usize::MAX)
.build_with_provider_factory(self.provider_factory.clone()); .build_with_provider_factory(self.provider_factory.clone());
pruner.run(prune_tip)?; pruner.run(prune_tip)?;

View File

@ -42,8 +42,7 @@ impl<DB: Database> Stage<DB> for PruneStage {
) -> Result<ExecOutput, StageError> { ) -> Result<ExecOutput, StageError> {
let mut pruner = PrunerBuilder::default() let mut pruner = PrunerBuilder::default()
.segments(self.prune_modes.clone()) .segments(self.prune_modes.clone())
.prune_max_blocks_per_run(1) .delete_limit(self.commit_threshold)
.delete_limit_per_block(self.commit_threshold)
.build(); .build();
let result = pruner.run(provider, input.target())?; let result = pruner.run(provider, input.target())?;