1. Added both options for measuring space usage using total accounts usage and for individual store shrink ratio using an enum. Validator CLI options: --accounts-shrink-optimize-total-space and --accounts-shrink-ratio 2. Added code for selecting candidates based on total usage in a separate function select_candidates_by_total_usage 3. Added unit tests for the new functions added 4. The default implementations is kept at 0.8 shrink ratio with --accounts-shrink-optimize-total-space set to true Fixes #17544
This commit is contained in:
parent
a1fab0c5ca
commit
269d995832
|
@ -6,6 +6,7 @@ use rayon::prelude::*;
|
||||||
use solana_measure::measure::Measure;
|
use solana_measure::measure::Measure;
|
||||||
use solana_runtime::{
|
use solana_runtime::{
|
||||||
accounts::{create_test_accounts, update_accounts_bench, Accounts},
|
accounts::{create_test_accounts, update_accounts_bench, Accounts},
|
||||||
|
accounts_db::AccountShrinkThreshold,
|
||||||
accounts_index::AccountSecondaryIndexes,
|
accounts_index::AccountSecondaryIndexes,
|
||||||
ancestors::Ancestors,
|
ancestors::Ancestors,
|
||||||
};
|
};
|
||||||
|
@ -64,6 +65,7 @@ fn main() {
|
||||||
&ClusterType::Testnet,
|
&ClusterType::Testnet,
|
||||||
AccountSecondaryIndexes::default(),
|
AccountSecondaryIndexes::default(),
|
||||||
false,
|
false,
|
||||||
|
AccountShrinkThreshold::default(),
|
||||||
);
|
);
|
||||||
println!("Creating {} accounts", num_accounts);
|
println!("Creating {} accounts", num_accounts);
|
||||||
let mut create_time = Measure::start("create accounts");
|
let mut create_time = Measure::start("create accounts");
|
||||||
|
|
|
@ -38,6 +38,7 @@ use solana_runtime::{
|
||||||
accounts_background_service::{
|
accounts_background_service::{
|
||||||
AbsRequestHandler, AbsRequestSender, AccountsBackgroundService, SnapshotRequestHandler,
|
AbsRequestHandler, AbsRequestSender, AccountsBackgroundService, SnapshotRequestHandler,
|
||||||
},
|
},
|
||||||
|
accounts_db::AccountShrinkThreshold,
|
||||||
bank_forks::{BankForks, SnapshotConfig},
|
bank_forks::{BankForks, SnapshotConfig},
|
||||||
commitment::BlockCommitmentCache,
|
commitment::BlockCommitmentCache,
|
||||||
vote_sender_types::ReplayVoteSender,
|
vote_sender_types::ReplayVoteSender,
|
||||||
|
@ -89,6 +90,7 @@ pub struct TvuConfig {
|
||||||
pub rocksdb_compaction_interval: Option<u64>,
|
pub rocksdb_compaction_interval: Option<u64>,
|
||||||
pub rocksdb_max_compaction_jitter: Option<u64>,
|
pub rocksdb_max_compaction_jitter: Option<u64>,
|
||||||
pub wait_for_vote_to_start_leader: bool,
|
pub wait_for_vote_to_start_leader: bool,
|
||||||
|
pub accounts_shrink_ratio: AccountShrinkThreshold,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Tvu {
|
impl Tvu {
|
||||||
|
|
|
@ -53,6 +53,7 @@ use solana_rpc::{
|
||||||
transaction_status_service::TransactionStatusService,
|
transaction_status_service::TransactionStatusService,
|
||||||
};
|
};
|
||||||
use solana_runtime::{
|
use solana_runtime::{
|
||||||
|
accounts_db::AccountShrinkThreshold,
|
||||||
accounts_index::AccountSecondaryIndexes,
|
accounts_index::AccountSecondaryIndexes,
|
||||||
bank::Bank,
|
bank::Bank,
|
||||||
bank_forks::{BankForks, SnapshotConfig},
|
bank_forks::{BankForks, SnapshotConfig},
|
||||||
|
@ -139,6 +140,7 @@ pub struct ValidatorConfig {
|
||||||
pub tpu_coalesce_ms: u64,
|
pub tpu_coalesce_ms: u64,
|
||||||
pub validator_exit: Arc<RwLock<Exit>>,
|
pub validator_exit: Arc<RwLock<Exit>>,
|
||||||
pub no_wait_for_vote_to_start_leader: bool,
|
pub no_wait_for_vote_to_start_leader: bool,
|
||||||
|
pub accounts_shrink_ratio: AccountShrinkThreshold,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for ValidatorConfig {
|
impl Default for ValidatorConfig {
|
||||||
|
@ -195,6 +197,7 @@ impl Default for ValidatorConfig {
|
||||||
tpu_coalesce_ms: DEFAULT_TPU_COALESCE_MS,
|
tpu_coalesce_ms: DEFAULT_TPU_COALESCE_MS,
|
||||||
validator_exit: Arc::new(RwLock::new(Exit::default())),
|
validator_exit: Arc::new(RwLock::new(Exit::default())),
|
||||||
no_wait_for_vote_to_start_leader: true,
|
no_wait_for_vote_to_start_leader: true,
|
||||||
|
accounts_shrink_ratio: AccountShrinkThreshold::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -726,6 +729,7 @@ impl Validator {
|
||||||
rocksdb_compaction_interval: config.rocksdb_compaction_interval,
|
rocksdb_compaction_interval: config.rocksdb_compaction_interval,
|
||||||
rocksdb_max_compaction_jitter: config.rocksdb_compaction_interval,
|
rocksdb_max_compaction_jitter: config.rocksdb_compaction_interval,
|
||||||
wait_for_vote_to_start_leader,
|
wait_for_vote_to_start_leader,
|
||||||
|
accounts_shrink_ratio: config.accounts_shrink_ratio,
|
||||||
},
|
},
|
||||||
&max_slots,
|
&max_slots,
|
||||||
&cost_model,
|
&cost_model,
|
||||||
|
@ -1099,6 +1103,7 @@ fn new_banks_from_ledger(
|
||||||
debug_keys: config.debug_keys.clone(),
|
debug_keys: config.debug_keys.clone(),
|
||||||
account_indexes: config.account_indexes.clone(),
|
account_indexes: config.account_indexes.clone(),
|
||||||
accounts_db_caching_enabled: config.accounts_db_caching_enabled,
|
accounts_db_caching_enabled: config.accounts_db_caching_enabled,
|
||||||
|
shrink_ratio: config.accounts_shrink_ratio,
|
||||||
..blockstore_processor::ProcessOptions::default()
|
..blockstore_processor::ProcessOptions::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -106,6 +106,7 @@ mod tests {
|
||||||
None,
|
None,
|
||||||
AccountSecondaryIndexes::default(),
|
AccountSecondaryIndexes::default(),
|
||||||
false,
|
false,
|
||||||
|
accounts_db::AccountShrinkThreshold::default(),
|
||||||
);
|
);
|
||||||
bank0.freeze();
|
bank0.freeze();
|
||||||
let mut bank_forks = BankForks::new(bank0);
|
let mut bank_forks = BankForks::new(bank0);
|
||||||
|
@ -165,6 +166,7 @@ mod tests {
|
||||||
AccountSecondaryIndexes::default(),
|
AccountSecondaryIndexes::default(),
|
||||||
false,
|
false,
|
||||||
None,
|
None,
|
||||||
|
accounts_db::AccountShrinkThreshold::default(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
|
|
@ -142,6 +142,7 @@ fn load_from_snapshot(
|
||||||
process_options.account_indexes.clone(),
|
process_options.account_indexes.clone(),
|
||||||
process_options.accounts_db_caching_enabled,
|
process_options.accounts_db_caching_enabled,
|
||||||
process_options.limit_load_slot_count_from_snapshot,
|
process_options.limit_load_slot_count_from_snapshot,
|
||||||
|
process_options.shrink_ratio,
|
||||||
)
|
)
|
||||||
.expect("Load from snapshot failed");
|
.expect("Load from snapshot failed");
|
||||||
if let Some(shrink_paths) = shrink_paths {
|
if let Some(shrink_paths) = shrink_paths {
|
||||||
|
|
|
@ -16,6 +16,7 @@ use solana_measure::measure::Measure;
|
||||||
use solana_metrics::{datapoint_error, inc_new_counter_debug};
|
use solana_metrics::{datapoint_error, inc_new_counter_debug};
|
||||||
use solana_rayon_threadlimit::get_thread_count;
|
use solana_rayon_threadlimit::get_thread_count;
|
||||||
use solana_runtime::{
|
use solana_runtime::{
|
||||||
|
accounts_db::AccountShrinkThreshold,
|
||||||
accounts_index::AccountSecondaryIndexes,
|
accounts_index::AccountSecondaryIndexes,
|
||||||
bank::{
|
bank::{
|
||||||
Bank, ExecuteTimings, InnerInstructionsList, RentDebits, TransactionBalancesSet,
|
Bank, ExecuteTimings, InnerInstructionsList, RentDebits, TransactionBalancesSet,
|
||||||
|
@ -373,6 +374,7 @@ pub struct ProcessOptions {
|
||||||
pub limit_load_slot_count_from_snapshot: Option<usize>,
|
pub limit_load_slot_count_from_snapshot: Option<usize>,
|
||||||
pub allow_dead_slots: bool,
|
pub allow_dead_slots: bool,
|
||||||
pub accounts_db_test_hash_calculation: bool,
|
pub accounts_db_test_hash_calculation: bool,
|
||||||
|
pub shrink_ratio: AccountShrinkThreshold,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn process_blockstore(
|
pub fn process_blockstore(
|
||||||
|
@ -400,6 +402,7 @@ pub fn process_blockstore(
|
||||||
Some(&crate::builtins::get(opts.bpf_jit)),
|
Some(&crate::builtins::get(opts.bpf_jit)),
|
||||||
opts.account_indexes.clone(),
|
opts.account_indexes.clone(),
|
||||||
opts.accounts_db_caching_enabled,
|
opts.accounts_db_caching_enabled,
|
||||||
|
opts.shrink_ratio,
|
||||||
);
|
);
|
||||||
let bank0 = Arc::new(bank0);
|
let bank0 = Arc::new(bank0);
|
||||||
info!("processing ledger for slot 0...");
|
info!("processing ledger for slot 0...");
|
||||||
|
@ -3064,6 +3067,7 @@ pub mod tests {
|
||||||
None,
|
None,
|
||||||
AccountSecondaryIndexes::default(),
|
AccountSecondaryIndexes::default(),
|
||||||
false,
|
false,
|
||||||
|
AccountShrinkThreshold::default(),
|
||||||
);
|
);
|
||||||
*bank.epoch_schedule()
|
*bank.epoch_schedule()
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,7 @@ pub fn safe_clone_config(config: &ValidatorConfig) -> ValidatorConfig {
|
||||||
validator_exit: Arc::new(RwLock::new(Exit::default())),
|
validator_exit: Arc::new(RwLock::new(Exit::default())),
|
||||||
poh_hashes_per_batch: config.poh_hashes_per_batch,
|
poh_hashes_per_batch: config.poh_hashes_per_batch,
|
||||||
no_wait_for_vote_to_start_leader: config.no_wait_for_vote_to_start_leader,
|
no_wait_for_vote_to_start_leader: config.no_wait_for_vote_to_start_leader,
|
||||||
|
accounts_shrink_ratio: config.accounts_shrink_ratio,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ use rand::Rng;
|
||||||
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
|
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
|
||||||
use solana_runtime::{
|
use solana_runtime::{
|
||||||
accounts::{create_test_accounts, AccountAddressFilter, Accounts},
|
accounts::{create_test_accounts, AccountAddressFilter, Accounts},
|
||||||
|
accounts_db::AccountShrinkThreshold,
|
||||||
accounts_index::AccountSecondaryIndexes,
|
accounts_index::AccountSecondaryIndexes,
|
||||||
ancestors::Ancestors,
|
ancestors::Ancestors,
|
||||||
bank::*,
|
bank::*,
|
||||||
|
@ -59,6 +60,7 @@ fn test_accounts_create(bencher: &mut Bencher) {
|
||||||
None,
|
None,
|
||||||
AccountSecondaryIndexes::default(),
|
AccountSecondaryIndexes::default(),
|
||||||
false,
|
false,
|
||||||
|
AccountShrinkThreshold::default(),
|
||||||
);
|
);
|
||||||
bencher.iter(|| {
|
bencher.iter(|| {
|
||||||
let mut pubkeys: Vec<Pubkey> = vec![];
|
let mut pubkeys: Vec<Pubkey> = vec![];
|
||||||
|
@ -78,6 +80,7 @@ fn test_accounts_squash(bencher: &mut Bencher) {
|
||||||
None,
|
None,
|
||||||
AccountSecondaryIndexes::default(),
|
AccountSecondaryIndexes::default(),
|
||||||
false,
|
false,
|
||||||
|
AccountShrinkThreshold::default(),
|
||||||
));
|
));
|
||||||
let mut pubkeys: Vec<Pubkey> = vec![];
|
let mut pubkeys: Vec<Pubkey> = vec![];
|
||||||
deposit_many(&prev_bank, &mut pubkeys, 250_000).unwrap();
|
deposit_many(&prev_bank, &mut pubkeys, 250_000).unwrap();
|
||||||
|
@ -103,6 +106,7 @@ fn test_accounts_hash_bank_hash(bencher: &mut Bencher) {
|
||||||
&ClusterType::Development,
|
&ClusterType::Development,
|
||||||
AccountSecondaryIndexes::default(),
|
AccountSecondaryIndexes::default(),
|
||||||
false,
|
false,
|
||||||
|
AccountShrinkThreshold::default(),
|
||||||
);
|
);
|
||||||
let mut pubkeys: Vec<Pubkey> = vec![];
|
let mut pubkeys: Vec<Pubkey> = vec![];
|
||||||
let num_accounts = 60_000;
|
let num_accounts = 60_000;
|
||||||
|
@ -121,6 +125,7 @@ fn test_update_accounts_hash(bencher: &mut Bencher) {
|
||||||
&ClusterType::Development,
|
&ClusterType::Development,
|
||||||
AccountSecondaryIndexes::default(),
|
AccountSecondaryIndexes::default(),
|
||||||
false,
|
false,
|
||||||
|
AccountShrinkThreshold::default(),
|
||||||
);
|
);
|
||||||
let mut pubkeys: Vec<Pubkey> = vec![];
|
let mut pubkeys: Vec<Pubkey> = vec![];
|
||||||
create_test_accounts(&accounts, &mut pubkeys, 50_000, 0);
|
create_test_accounts(&accounts, &mut pubkeys, 50_000, 0);
|
||||||
|
@ -138,6 +143,7 @@ fn test_accounts_delta_hash(bencher: &mut Bencher) {
|
||||||
&ClusterType::Development,
|
&ClusterType::Development,
|
||||||
AccountSecondaryIndexes::default(),
|
AccountSecondaryIndexes::default(),
|
||||||
false,
|
false,
|
||||||
|
AccountShrinkThreshold::default(),
|
||||||
);
|
);
|
||||||
let mut pubkeys: Vec<Pubkey> = vec![];
|
let mut pubkeys: Vec<Pubkey> = vec![];
|
||||||
create_test_accounts(&accounts, &mut pubkeys, 100_000, 0);
|
create_test_accounts(&accounts, &mut pubkeys, 100_000, 0);
|
||||||
|
@ -154,6 +160,7 @@ fn bench_delete_dependencies(bencher: &mut Bencher) {
|
||||||
&ClusterType::Development,
|
&ClusterType::Development,
|
||||||
AccountSecondaryIndexes::default(),
|
AccountSecondaryIndexes::default(),
|
||||||
false,
|
false,
|
||||||
|
AccountShrinkThreshold::default(),
|
||||||
);
|
);
|
||||||
let mut old_pubkey = Pubkey::default();
|
let mut old_pubkey = Pubkey::default();
|
||||||
let zero_account = AccountSharedData::new(0, 0, AccountSharedData::default().owner());
|
let zero_account = AccountSharedData::new(0, 0, AccountSharedData::default().owner());
|
||||||
|
@ -187,6 +194,7 @@ fn store_accounts_with_possible_contention<F: 'static>(
|
||||||
&ClusterType::Development,
|
&ClusterType::Development,
|
||||||
AccountSecondaryIndexes::default(),
|
AccountSecondaryIndexes::default(),
|
||||||
false,
|
false,
|
||||||
|
AccountShrinkThreshold::default(),
|
||||||
));
|
));
|
||||||
let num_keys = 1000;
|
let num_keys = 1000;
|
||||||
let slot = 0;
|
let slot = 0;
|
||||||
|
@ -316,6 +324,7 @@ fn setup_bench_dashmap_iter() -> (Arc<Accounts>, DashMap<Pubkey, (AccountSharedD
|
||||||
&ClusterType::Development,
|
&ClusterType::Development,
|
||||||
AccountSecondaryIndexes::default(),
|
AccountSecondaryIndexes::default(),
|
||||||
false,
|
false,
|
||||||
|
AccountShrinkThreshold::default(),
|
||||||
));
|
));
|
||||||
|
|
||||||
let dashmap = DashMap::new();
|
let dashmap = DashMap::new();
|
||||||
|
@ -370,6 +379,7 @@ fn bench_load_largest_accounts(b: &mut Bencher) {
|
||||||
&ClusterType::Development,
|
&ClusterType::Development,
|
||||||
AccountSecondaryIndexes::default(),
|
AccountSecondaryIndexes::default(),
|
||||||
false,
|
false,
|
||||||
|
AccountShrinkThreshold::default(),
|
||||||
);
|
);
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::thread_rng();
|
||||||
for _ in 0..10_000 {
|
for _ in 0..10_000 {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
accounts_db::{
|
accounts_db::{
|
||||||
AccountsDb, BankHashInfo, ErrorCounters, LoadHint, LoadedAccount, ScanStorageResult,
|
AccountShrinkThreshold, AccountsDb, BankHashInfo, ErrorCounters, LoadHint, LoadedAccount,
|
||||||
|
ScanStorageResult,
|
||||||
},
|
},
|
||||||
accounts_index::{AccountSecondaryIndexes, IndexKey},
|
accounts_index::{AccountSecondaryIndexes, IndexKey},
|
||||||
ancestors::Ancestors,
|
ancestors::Ancestors,
|
||||||
|
@ -117,12 +118,17 @@ pub enum AccountAddressFilter {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Accounts {
|
impl Accounts {
|
||||||
pub fn new(paths: Vec<PathBuf>, cluster_type: &ClusterType) -> Self {
|
pub fn new(
|
||||||
|
paths: Vec<PathBuf>,
|
||||||
|
cluster_type: &ClusterType,
|
||||||
|
shrink_ratio: AccountShrinkThreshold,
|
||||||
|
) -> Self {
|
||||||
Self::new_with_config(
|
Self::new_with_config(
|
||||||
paths,
|
paths,
|
||||||
cluster_type,
|
cluster_type,
|
||||||
AccountSecondaryIndexes::default(),
|
AccountSecondaryIndexes::default(),
|
||||||
false,
|
false,
|
||||||
|
shrink_ratio,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,6 +137,7 @@ impl Accounts {
|
||||||
cluster_type: &ClusterType,
|
cluster_type: &ClusterType,
|
||||||
account_indexes: AccountSecondaryIndexes,
|
account_indexes: AccountSecondaryIndexes,
|
||||||
caching_enabled: bool,
|
caching_enabled: bool,
|
||||||
|
shrink_ratio: AccountShrinkThreshold,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
accounts_db: Arc::new(AccountsDb::new_with_config(
|
accounts_db: Arc::new(AccountsDb::new_with_config(
|
||||||
|
@ -138,6 +145,7 @@ impl Accounts {
|
||||||
cluster_type,
|
cluster_type,
|
||||||
account_indexes,
|
account_indexes,
|
||||||
caching_enabled,
|
caching_enabled,
|
||||||
|
shrink_ratio,
|
||||||
)),
|
)),
|
||||||
account_locks: Mutex::new(AccountLocks::default()),
|
account_locks: Mutex::new(AccountLocks::default()),
|
||||||
}
|
}
|
||||||
|
@ -1118,6 +1126,7 @@ mod tests {
|
||||||
&ClusterType::Development,
|
&ClusterType::Development,
|
||||||
AccountSecondaryIndexes::default(),
|
AccountSecondaryIndexes::default(),
|
||||||
false,
|
false,
|
||||||
|
AccountShrinkThreshold::default(),
|
||||||
);
|
);
|
||||||
for ka in ka.iter() {
|
for ka in ka.iter() {
|
||||||
accounts.store_slow_uncached(0, &ka.0, &ka.1);
|
accounts.store_slow_uncached(0, &ka.0, &ka.1);
|
||||||
|
@ -1655,6 +1664,7 @@ mod tests {
|
||||||
&ClusterType::Development,
|
&ClusterType::Development,
|
||||||
AccountSecondaryIndexes::default(),
|
AccountSecondaryIndexes::default(),
|
||||||
false,
|
false,
|
||||||
|
AccountShrinkThreshold::default(),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Load accounts owned by various programs into AccountsDb
|
// Load accounts owned by various programs into AccountsDb
|
||||||
|
@ -1683,6 +1693,7 @@ mod tests {
|
||||||
&ClusterType::Development,
|
&ClusterType::Development,
|
||||||
AccountSecondaryIndexes::default(),
|
AccountSecondaryIndexes::default(),
|
||||||
false,
|
false,
|
||||||
|
AccountShrinkThreshold::default(),
|
||||||
);
|
);
|
||||||
let mut error_counters = ErrorCounters::default();
|
let mut error_counters = ErrorCounters::default();
|
||||||
let ancestors = vec![(0, 0)].into_iter().collect();
|
let ancestors = vec![(0, 0)].into_iter().collect();
|
||||||
|
@ -1706,6 +1717,7 @@ mod tests {
|
||||||
&ClusterType::Development,
|
&ClusterType::Development,
|
||||||
AccountSecondaryIndexes::default(),
|
AccountSecondaryIndexes::default(),
|
||||||
false,
|
false,
|
||||||
|
AccountShrinkThreshold::default(),
|
||||||
);
|
);
|
||||||
accounts.bank_hash_at(1);
|
accounts.bank_hash_at(1);
|
||||||
}
|
}
|
||||||
|
@ -1727,6 +1739,7 @@ mod tests {
|
||||||
&ClusterType::Development,
|
&ClusterType::Development,
|
||||||
AccountSecondaryIndexes::default(),
|
AccountSecondaryIndexes::default(),
|
||||||
false,
|
false,
|
||||||
|
AccountShrinkThreshold::default(),
|
||||||
);
|
);
|
||||||
accounts.store_slow_uncached(0, &keypair0.pubkey(), &account0);
|
accounts.store_slow_uncached(0, &keypair0.pubkey(), &account0);
|
||||||
accounts.store_slow_uncached(0, &keypair1.pubkey(), &account1);
|
accounts.store_slow_uncached(0, &keypair1.pubkey(), &account1);
|
||||||
|
@ -1853,6 +1866,7 @@ mod tests {
|
||||||
&ClusterType::Development,
|
&ClusterType::Development,
|
||||||
AccountSecondaryIndexes::default(),
|
AccountSecondaryIndexes::default(),
|
||||||
false,
|
false,
|
||||||
|
AccountShrinkThreshold::default(),
|
||||||
);
|
);
|
||||||
accounts.store_slow_uncached(0, &keypair0.pubkey(), &account0);
|
accounts.store_slow_uncached(0, &keypair0.pubkey(), &account0);
|
||||||
accounts.store_slow_uncached(0, &keypair1.pubkey(), &account1);
|
accounts.store_slow_uncached(0, &keypair1.pubkey(), &account1);
|
||||||
|
@ -2003,6 +2017,7 @@ mod tests {
|
||||||
&ClusterType::Development,
|
&ClusterType::Development,
|
||||||
AccountSecondaryIndexes::default(),
|
AccountSecondaryIndexes::default(),
|
||||||
false,
|
false,
|
||||||
|
AccountShrinkThreshold::default(),
|
||||||
);
|
);
|
||||||
{
|
{
|
||||||
accounts
|
accounts
|
||||||
|
@ -2055,6 +2070,7 @@ mod tests {
|
||||||
&ClusterType::Development,
|
&ClusterType::Development,
|
||||||
AccountSecondaryIndexes::default(),
|
AccountSecondaryIndexes::default(),
|
||||||
false,
|
false,
|
||||||
|
AccountShrinkThreshold::default(),
|
||||||
);
|
);
|
||||||
let mut old_pubkey = Pubkey::default();
|
let mut old_pubkey = Pubkey::default();
|
||||||
let zero_account = AccountSharedData::new(0, 0, AccountSharedData::default().owner());
|
let zero_account = AccountSharedData::new(0, 0, AccountSharedData::default().owner());
|
||||||
|
@ -2102,6 +2118,7 @@ mod tests {
|
||||||
&ClusterType::Development,
|
&ClusterType::Development,
|
||||||
AccountSecondaryIndexes::default(),
|
AccountSecondaryIndexes::default(),
|
||||||
false,
|
false,
|
||||||
|
AccountShrinkThreshold::default(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let instructions_key = solana_sdk::sysvar::instructions::id();
|
let instructions_key = solana_sdk::sysvar::instructions::id();
|
||||||
|
@ -2387,6 +2404,7 @@ mod tests {
|
||||||
&ClusterType::Development,
|
&ClusterType::Development,
|
||||||
AccountSecondaryIndexes::default(),
|
AccountSecondaryIndexes::default(),
|
||||||
false,
|
false,
|
||||||
|
AccountShrinkThreshold::default(),
|
||||||
);
|
);
|
||||||
let collected_accounts = accounts.collect_accounts_to_store(
|
let collected_accounts = accounts.collect_accounts_to_store(
|
||||||
txs.iter(),
|
txs.iter(),
|
||||||
|
@ -2506,6 +2524,7 @@ mod tests {
|
||||||
&ClusterType::Development,
|
&ClusterType::Development,
|
||||||
AccountSecondaryIndexes::default(),
|
AccountSecondaryIndexes::default(),
|
||||||
false,
|
false,
|
||||||
|
AccountShrinkThreshold::default(),
|
||||||
);
|
);
|
||||||
let collected_accounts = accounts.collect_accounts_to_store(
|
let collected_accounts = accounts.collect_accounts_to_store(
|
||||||
txs.iter(),
|
txs.iter(),
|
||||||
|
@ -2540,6 +2559,7 @@ mod tests {
|
||||||
&ClusterType::Development,
|
&ClusterType::Development,
|
||||||
AccountSecondaryIndexes::default(),
|
AccountSecondaryIndexes::default(),
|
||||||
false,
|
false,
|
||||||
|
AccountShrinkThreshold::default(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let pubkey0 = Pubkey::new_unique();
|
let pubkey0 = Pubkey::new_unique();
|
||||||
|
|
|
@ -82,7 +82,6 @@ const SCAN_SLOT_PAR_ITER_THRESHOLD: usize = 4000;
|
||||||
pub const DEFAULT_FILE_SIZE: u64 = PAGE_SIZE * 1024;
|
pub const DEFAULT_FILE_SIZE: u64 = PAGE_SIZE * 1024;
|
||||||
pub const DEFAULT_NUM_THREADS: u32 = 8;
|
pub const DEFAULT_NUM_THREADS: u32 = 8;
|
||||||
pub const DEFAULT_NUM_DIRS: u32 = 4;
|
pub const DEFAULT_NUM_DIRS: u32 = 4;
|
||||||
pub const SHRINK_RATIO: f64 = 0.80;
|
|
||||||
|
|
||||||
// A specially reserved storage id just for entries in the cache, so that
|
// A specially reserved storage id just for entries in the cache, so that
|
||||||
// operations that take a storage entry can maintain a common interface
|
// operations that take a storage entry can maintain a common interface
|
||||||
|
@ -114,6 +113,31 @@ lazy_static! {
|
||||||
pub static ref FROZEN_ACCOUNT_PANIC: Arc<AtomicBool> = Arc::new(AtomicBool::new(false));
|
pub static ref FROZEN_ACCOUNT_PANIC: Arc<AtomicBool> = Arc::new(AtomicBool::new(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub enum AccountShrinkThreshold {
|
||||||
|
/// Measure the total space sparseness across all candididates
|
||||||
|
/// And select the candidiates by using the top sparse account storage entries to shrink.
|
||||||
|
/// The value is the overall shrink threshold measured as ratio of the total live bytes
|
||||||
|
/// over the total bytes.
|
||||||
|
TotalSpace { shrink_ratio: f64 },
|
||||||
|
/// Use the following option to shrink all stores whose alive ratio is below
|
||||||
|
/// the specified threshold.
|
||||||
|
IndividalStore { shrink_ratio: f64 },
|
||||||
|
}
|
||||||
|
pub const DEFAULT_ACCOUNTS_SHRINK_OPTIMIZE_TOTAL_SPACE: bool = true;
|
||||||
|
pub const DEFAULT_ACCOUNTS_SHRINK_RATIO: f64 = 0.80;
|
||||||
|
// The default extra account space in percentage from the ideal target
|
||||||
|
const DEFAULT_ACCOUNTS_SHRINK_THRESHOLD_OPTION: AccountShrinkThreshold =
|
||||||
|
AccountShrinkThreshold::TotalSpace {
|
||||||
|
shrink_ratio: DEFAULT_ACCOUNTS_SHRINK_RATIO,
|
||||||
|
};
|
||||||
|
|
||||||
|
impl Default for AccountShrinkThreshold {
|
||||||
|
fn default() -> AccountShrinkThreshold {
|
||||||
|
DEFAULT_ACCOUNTS_SHRINK_THRESHOLD_OPTION
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub enum ScanStorageResult<R, B> {
|
pub enum ScanStorageResult<R, B> {
|
||||||
Cached(Vec<R>),
|
Cached(Vec<R>),
|
||||||
Stored(B),
|
Stored(B),
|
||||||
|
@ -850,6 +874,8 @@ pub struct AccountsDb {
|
||||||
/// by `remove_unrooted_slot()`. Used to ensure `remove_unrooted_slots(slots)`
|
/// by `remove_unrooted_slot()`. Used to ensure `remove_unrooted_slots(slots)`
|
||||||
/// can safely clear the set of unrooted slots `slots`.
|
/// can safely clear the set of unrooted slots `slots`.
|
||||||
remove_unrooted_slots_synchronization: RemoveUnrootedSlotsSynchronization,
|
remove_unrooted_slots_synchronization: RemoveUnrootedSlotsSynchronization,
|
||||||
|
|
||||||
|
shrink_ratio: AccountShrinkThreshold,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
|
@ -1293,6 +1319,7 @@ impl Default for AccountsDb {
|
||||||
load_limit: AtomicU64::default(),
|
load_limit: AtomicU64::default(),
|
||||||
is_bank_drop_callback_enabled: AtomicBool::default(),
|
is_bank_drop_callback_enabled: AtomicBool::default(),
|
||||||
remove_unrooted_slots_synchronization: RemoveUnrootedSlotsSynchronization::default(),
|
remove_unrooted_slots_synchronization: RemoveUnrootedSlotsSynchronization::default(),
|
||||||
|
shrink_ratio: AccountShrinkThreshold::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1304,6 +1331,7 @@ impl AccountsDb {
|
||||||
cluster_type,
|
cluster_type,
|
||||||
AccountSecondaryIndexes::default(),
|
AccountSecondaryIndexes::default(),
|
||||||
false,
|
false,
|
||||||
|
AccountShrinkThreshold::default(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1312,6 +1340,7 @@ impl AccountsDb {
|
||||||
cluster_type: &ClusterType,
|
cluster_type: &ClusterType,
|
||||||
account_indexes: AccountSecondaryIndexes,
|
account_indexes: AccountSecondaryIndexes,
|
||||||
caching_enabled: bool,
|
caching_enabled: bool,
|
||||||
|
shrink_ratio: AccountShrinkThreshold,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mut new = if !paths.is_empty() {
|
let mut new = if !paths.is_empty() {
|
||||||
Self {
|
Self {
|
||||||
|
@ -1320,6 +1349,7 @@ impl AccountsDb {
|
||||||
cluster_type: Some(*cluster_type),
|
cluster_type: Some(*cluster_type),
|
||||||
account_indexes,
|
account_indexes,
|
||||||
caching_enabled,
|
caching_enabled,
|
||||||
|
shrink_ratio,
|
||||||
..Self::default()
|
..Self::default()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1332,6 +1362,7 @@ impl AccountsDb {
|
||||||
cluster_type: Some(*cluster_type),
|
cluster_type: Some(*cluster_type),
|
||||||
account_indexes,
|
account_indexes,
|
||||||
caching_enabled,
|
caching_enabled,
|
||||||
|
shrink_ratio,
|
||||||
..Self::default()
|
..Self::default()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -2267,15 +2298,105 @@ impl AccountsDb {
|
||||||
self.accounts_index.all_roots()
|
self.accounts_index.all_roots()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn shrink_candidate_slots(&self) -> usize {
|
/// Given the input `ShrinkCandidates`, this function sorts the stores by their alive ratio
|
||||||
let shrink_slots = std::mem::take(&mut *self.shrink_candidate_slots.lock().unwrap());
|
/// in increasing order with the most sparse entries in the front. It will then simulate the
|
||||||
let num_candidates = shrink_slots.len();
|
/// shrinking by working on the most sparse entries first and if the overall alive ratio is
|
||||||
|
/// achieved, it will stop and return the filtered-down candidates.
|
||||||
|
fn select_candidates_by_total_usage(
|
||||||
|
&self,
|
||||||
|
shrink_slots: &ShrinkCandidates,
|
||||||
|
shrink_ratio: f64,
|
||||||
|
) -> ShrinkCandidates {
|
||||||
|
struct StoreUsageInfo {
|
||||||
|
slot: Slot,
|
||||||
|
alive_ratio: f64,
|
||||||
|
store: Arc<AccountStorageEntry>,
|
||||||
|
}
|
||||||
|
let mut measure = Measure::start("select_top_sparse_storage_entries-ms");
|
||||||
|
let mut store_usage: Vec<StoreUsageInfo> = Vec::with_capacity(shrink_slots.len());
|
||||||
|
let mut total_alive_bytes: u64 = 0;
|
||||||
|
let mut candidates_count: usize = 0;
|
||||||
|
let mut total_bytes: u64 = 0;
|
||||||
for (slot, slot_shrink_candidates) in shrink_slots {
|
for (slot, slot_shrink_candidates) in shrink_slots {
|
||||||
|
candidates_count += slot_shrink_candidates.len();
|
||||||
|
for store in slot_shrink_candidates.values() {
|
||||||
|
total_alive_bytes += Self::page_align(store.alive_bytes() as u64);
|
||||||
|
total_bytes += store.total_bytes();
|
||||||
|
let alive_ratio = Self::page_align(store.alive_bytes() as u64) as f64
|
||||||
|
/ store.total_bytes() as f64;
|
||||||
|
store_usage.push(StoreUsageInfo {
|
||||||
|
slot: *slot,
|
||||||
|
alive_ratio,
|
||||||
|
store: store.clone(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
store_usage.sort_by(|a, b| {
|
||||||
|
a.alive_ratio
|
||||||
|
.partial_cmp(&b.alive_ratio)
|
||||||
|
.unwrap_or(std::cmp::Ordering::Equal)
|
||||||
|
});
|
||||||
|
|
||||||
|
// Working from the beginning of store_usage which are the most sparse and see when we can stop
|
||||||
|
// shrinking while still achieving the overall goals.
|
||||||
|
let mut shrink_slots: ShrinkCandidates = HashMap::new();
|
||||||
|
for usage in &store_usage {
|
||||||
|
let alive_ratio = (total_alive_bytes as f64) / (total_bytes as f64);
|
||||||
|
if alive_ratio > shrink_ratio {
|
||||||
|
// we have reached our goal, stop
|
||||||
|
debug!(
|
||||||
|
"Shrinking goal can be achieved at slot {:?}, total_alive_bytes: {:?} \
|
||||||
|
total_bytes: {:?}, alive_ratio: {:}, shrink_ratio: {:?}",
|
||||||
|
usage.slot, total_alive_bytes, total_bytes, alive_ratio, shrink_ratio
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
let store = &usage.store;
|
||||||
|
let current_store_size = store.total_bytes();
|
||||||
|
let after_shrink_size = Self::page_align(store.alive_bytes() as u64);
|
||||||
|
let bytes_saved = current_store_size.saturating_sub(after_shrink_size);
|
||||||
|
total_bytes -= bytes_saved;
|
||||||
|
shrink_slots
|
||||||
|
.entry(usage.slot)
|
||||||
|
.or_default()
|
||||||
|
.insert(store.append_vec_id(), store.clone());
|
||||||
|
}
|
||||||
|
measure.stop();
|
||||||
|
inc_new_counter_info!(
|
||||||
|
"select_top_sparse_storage_entries-ms",
|
||||||
|
measure.as_ms() as usize
|
||||||
|
);
|
||||||
|
inc_new_counter_info!("select_top_sparse_storage_entries-seeds", candidates_count);
|
||||||
|
shrink_slots
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn shrink_candidate_slots(&self) -> usize {
|
||||||
|
let shrink_candidates_slots =
|
||||||
|
std::mem::take(&mut *self.shrink_candidate_slots.lock().unwrap());
|
||||||
|
let shrink_slots = {
|
||||||
|
if let AccountShrinkThreshold::TotalSpace { shrink_ratio } = self.shrink_ratio {
|
||||||
|
self.select_candidates_by_total_usage(&shrink_candidates_slots, shrink_ratio)
|
||||||
|
} else {
|
||||||
|
shrink_candidates_slots
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut measure_shrink_all_candidates = Measure::start("shrink_all_candidate_slots-ms");
|
||||||
|
let num_candidates = shrink_slots.len();
|
||||||
|
let mut shrink_candidates_count: usize = 0;
|
||||||
|
for (slot, slot_shrink_candidates) in shrink_slots {
|
||||||
|
shrink_candidates_count += slot_shrink_candidates.len();
|
||||||
let mut measure = Measure::start("shrink_candidate_slots-ms");
|
let mut measure = Measure::start("shrink_candidate_slots-ms");
|
||||||
self.do_shrink_slot_stores(slot, slot_shrink_candidates.values(), false);
|
self.do_shrink_slot_stores(slot, slot_shrink_candidates.values(), false);
|
||||||
measure.stop();
|
measure.stop();
|
||||||
inc_new_counter_info!("shrink_candidate_slots-ms", measure.as_ms() as usize);
|
inc_new_counter_info!("shrink_candidate_slots-ms", measure.as_ms() as usize);
|
||||||
}
|
}
|
||||||
|
measure_shrink_all_candidates.stop();
|
||||||
|
inc_new_counter_info!(
|
||||||
|
"shrink_all_candidate_slots-ms",
|
||||||
|
measure_shrink_all_candidates.as_ms() as usize
|
||||||
|
);
|
||||||
|
inc_new_counter_info!("shrink_all_candidate_slots-count", shrink_candidates_count);
|
||||||
num_candidates
|
num_candidates
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4818,6 +4939,18 @@ impl AccountsDb {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_candidate_for_shrink(&self, store: &Arc<AccountStorageEntry>) -> bool {
|
||||||
|
match self.shrink_ratio {
|
||||||
|
AccountShrinkThreshold::TotalSpace { shrink_ratio: _ } => {
|
||||||
|
Self::page_align(store.alive_bytes() as u64) < store.total_bytes()
|
||||||
|
}
|
||||||
|
AccountShrinkThreshold::IndividalStore { shrink_ratio } => {
|
||||||
|
(Self::page_align(store.alive_bytes() as u64) as f64 / store.total_bytes() as f64)
|
||||||
|
< shrink_ratio
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn remove_dead_accounts(
|
fn remove_dead_accounts(
|
||||||
&self,
|
&self,
|
||||||
reclaims: SlotSlice<AccountInfo>,
|
reclaims: SlotSlice<AccountInfo>,
|
||||||
|
@ -4853,9 +4986,7 @@ impl AccountsDb {
|
||||||
dead_slots.insert(*slot);
|
dead_slots.insert(*slot);
|
||||||
} else if self.caching_enabled
|
} else if self.caching_enabled
|
||||||
&& Self::is_shrinking_productive(*slot, &[store.clone()])
|
&& Self::is_shrinking_productive(*slot, &[store.clone()])
|
||||||
&& (Self::page_align(store.alive_bytes() as u64) as f64
|
&& self.is_candidate_for_shrink(&store)
|
||||||
/ store.total_bytes() as f64)
|
|
||||||
< SHRINK_RATIO
|
|
||||||
{
|
{
|
||||||
// Checking that this single storage entry is ready for shrinking,
|
// Checking that this single storage entry is ready for shrinking,
|
||||||
// should be a sufficient indication that the slot is ready to be shrunk
|
// should be a sufficient indication that the slot is ready to be shrunk
|
||||||
|
@ -7343,6 +7474,7 @@ pub mod tests {
|
||||||
&ClusterType::Development,
|
&ClusterType::Development,
|
||||||
spl_token_mint_index_enabled(),
|
spl_token_mint_index_enabled(),
|
||||||
false,
|
false,
|
||||||
|
AccountShrinkThreshold::default(),
|
||||||
);
|
);
|
||||||
let pubkey1 = solana_sdk::pubkey::new_rand();
|
let pubkey1 = solana_sdk::pubkey::new_rand();
|
||||||
let pubkey2 = solana_sdk::pubkey::new_rand();
|
let pubkey2 = solana_sdk::pubkey::new_rand();
|
||||||
|
@ -9148,6 +9280,99 @@ pub mod tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_select_candidates_by_total_usage() {
|
||||||
|
solana_logger::setup();
|
||||||
|
|
||||||
|
// case 1: no candidates
|
||||||
|
let accounts = AccountsDb::new_single();
|
||||||
|
|
||||||
|
let mut candidates: ShrinkCandidates = HashMap::new();
|
||||||
|
let output_candidates =
|
||||||
|
accounts.select_candidates_by_total_usage(&candidates, DEFAULT_ACCOUNTS_SHRINK_RATIO);
|
||||||
|
|
||||||
|
assert_eq!(0, output_candidates.len());
|
||||||
|
|
||||||
|
// case 2: two candidates, only one selected
|
||||||
|
let dummy_path = Path::new("");
|
||||||
|
let dummy_slot = 12;
|
||||||
|
let dummy_size = 2 * PAGE_SIZE;
|
||||||
|
|
||||||
|
let dummy_id1 = 22;
|
||||||
|
let entry1 = Arc::new(AccountStorageEntry::new(
|
||||||
|
&dummy_path,
|
||||||
|
dummy_slot,
|
||||||
|
dummy_id1,
|
||||||
|
dummy_size,
|
||||||
|
));
|
||||||
|
entry1.alive_bytes.store(8000, Ordering::Relaxed);
|
||||||
|
|
||||||
|
candidates
|
||||||
|
.entry(dummy_slot)
|
||||||
|
.or_default()
|
||||||
|
.insert(entry1.append_vec_id(), entry1.clone());
|
||||||
|
|
||||||
|
let dummy_id2 = 44;
|
||||||
|
let entry2 = Arc::new(AccountStorageEntry::new(
|
||||||
|
&dummy_path,
|
||||||
|
dummy_slot,
|
||||||
|
dummy_id2,
|
||||||
|
dummy_size,
|
||||||
|
));
|
||||||
|
entry2.alive_bytes.store(3000, Ordering::Relaxed);
|
||||||
|
candidates
|
||||||
|
.entry(dummy_slot)
|
||||||
|
.or_default()
|
||||||
|
.insert(entry2.append_vec_id(), entry2.clone());
|
||||||
|
|
||||||
|
let output_candidates =
|
||||||
|
accounts.select_candidates_by_total_usage(&candidates, DEFAULT_ACCOUNTS_SHRINK_RATIO);
|
||||||
|
assert_eq!(1, output_candidates.len());
|
||||||
|
assert_eq!(1, output_candidates[&dummy_slot].len());
|
||||||
|
assert!(output_candidates[&dummy_slot].contains(&entry2.append_vec_id()));
|
||||||
|
|
||||||
|
// case 3: two candidates, both are selected
|
||||||
|
candidates.clear();
|
||||||
|
let dummy_size = 4 * PAGE_SIZE;
|
||||||
|
let dummy_id1 = 22;
|
||||||
|
let entry1 = Arc::new(AccountStorageEntry::new(
|
||||||
|
&dummy_path,
|
||||||
|
dummy_slot,
|
||||||
|
dummy_id1,
|
||||||
|
dummy_size,
|
||||||
|
));
|
||||||
|
entry1.alive_bytes.store(3500, Ordering::Relaxed);
|
||||||
|
|
||||||
|
candidates
|
||||||
|
.entry(dummy_slot)
|
||||||
|
.or_default()
|
||||||
|
.insert(entry1.append_vec_id(), entry1.clone());
|
||||||
|
|
||||||
|
let dummy_id2 = 44;
|
||||||
|
let dummy_slot2 = 44;
|
||||||
|
let entry2 = Arc::new(AccountStorageEntry::new(
|
||||||
|
&dummy_path,
|
||||||
|
dummy_slot2,
|
||||||
|
dummy_id2,
|
||||||
|
dummy_size,
|
||||||
|
));
|
||||||
|
entry2.alive_bytes.store(3000, Ordering::Relaxed);
|
||||||
|
|
||||||
|
candidates
|
||||||
|
.entry(dummy_slot2)
|
||||||
|
.or_default()
|
||||||
|
.insert(entry2.append_vec_id(), entry2.clone());
|
||||||
|
|
||||||
|
let output_candidates =
|
||||||
|
accounts.select_candidates_by_total_usage(&candidates, DEFAULT_ACCOUNTS_SHRINK_RATIO);
|
||||||
|
assert_eq!(2, output_candidates.len());
|
||||||
|
assert_eq!(1, output_candidates[&dummy_slot].len());
|
||||||
|
assert_eq!(1, output_candidates[&dummy_slot2].len());
|
||||||
|
|
||||||
|
assert!(output_candidates[&dummy_slot].contains(&entry1.append_vec_id()));
|
||||||
|
assert!(output_candidates[&dummy_slot2].contains(&entry2.append_vec_id()));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_shrink_stale_slots_skipped() {
|
fn test_shrink_stale_slots_skipped() {
|
||||||
solana_logger::setup();
|
solana_logger::setup();
|
||||||
|
@ -9646,6 +9871,7 @@ pub mod tests {
|
||||||
&ClusterType::Development,
|
&ClusterType::Development,
|
||||||
AccountSecondaryIndexes::default(),
|
AccountSecondaryIndexes::default(),
|
||||||
caching_enabled,
|
caching_enabled,
|
||||||
|
AccountShrinkThreshold::default(),
|
||||||
));
|
));
|
||||||
|
|
||||||
let account_key = Pubkey::new_unique();
|
let account_key = Pubkey::new_unique();
|
||||||
|
@ -9693,6 +9919,7 @@ pub mod tests {
|
||||||
&ClusterType::Development,
|
&ClusterType::Development,
|
||||||
AccountSecondaryIndexes::default(),
|
AccountSecondaryIndexes::default(),
|
||||||
caching_enabled,
|
caching_enabled,
|
||||||
|
AccountShrinkThreshold::default(),
|
||||||
));
|
));
|
||||||
|
|
||||||
let account_key = Pubkey::new_unique();
|
let account_key = Pubkey::new_unique();
|
||||||
|
@ -9741,6 +9968,7 @@ pub mod tests {
|
||||||
&ClusterType::Development,
|
&ClusterType::Development,
|
||||||
AccountSecondaryIndexes::default(),
|
AccountSecondaryIndexes::default(),
|
||||||
caching_enabled,
|
caching_enabled,
|
||||||
|
AccountShrinkThreshold::default(),
|
||||||
));
|
));
|
||||||
|
|
||||||
let zero_lamport_account_key = Pubkey::new_unique();
|
let zero_lamport_account_key = Pubkey::new_unique();
|
||||||
|
@ -9872,6 +10100,7 @@ pub mod tests {
|
||||||
&ClusterType::Development,
|
&ClusterType::Development,
|
||||||
AccountSecondaryIndexes::default(),
|
AccountSecondaryIndexes::default(),
|
||||||
caching_enabled,
|
caching_enabled,
|
||||||
|
AccountShrinkThreshold::default(),
|
||||||
));
|
));
|
||||||
let account_key = Pubkey::new_unique();
|
let account_key = Pubkey::new_unique();
|
||||||
let account_key2 = Pubkey::new_unique();
|
let account_key2 = Pubkey::new_unique();
|
||||||
|
@ -9976,6 +10205,7 @@ pub mod tests {
|
||||||
&ClusterType::Development,
|
&ClusterType::Development,
|
||||||
AccountSecondaryIndexes::default(),
|
AccountSecondaryIndexes::default(),
|
||||||
caching_enabled,
|
caching_enabled,
|
||||||
|
AccountShrinkThreshold::default(),
|
||||||
);
|
);
|
||||||
let slot: Slot = 0;
|
let slot: Slot = 0;
|
||||||
let num_keys = 10;
|
let num_keys = 10;
|
||||||
|
@ -10030,6 +10260,7 @@ pub mod tests {
|
||||||
&ClusterType::Development,
|
&ClusterType::Development,
|
||||||
AccountSecondaryIndexes::default(),
|
AccountSecondaryIndexes::default(),
|
||||||
caching_enabled,
|
caching_enabled,
|
||||||
|
AccountShrinkThreshold::default(),
|
||||||
));
|
));
|
||||||
let slots: Vec<_> = (0..num_slots as Slot).into_iter().collect();
|
let slots: Vec<_> = (0..num_slots as Slot).into_iter().collect();
|
||||||
let stall_slot = num_slots as Slot;
|
let stall_slot = num_slots as Slot;
|
||||||
|
@ -10428,6 +10659,7 @@ pub mod tests {
|
||||||
&ClusterType::Development,
|
&ClusterType::Development,
|
||||||
AccountSecondaryIndexes::default(),
|
AccountSecondaryIndexes::default(),
|
||||||
caching_enabled,
|
caching_enabled,
|
||||||
|
AccountShrinkThreshold::default(),
|
||||||
);
|
);
|
||||||
let account_key1 = Pubkey::new_unique();
|
let account_key1 = Pubkey::new_unique();
|
||||||
let account_key2 = Pubkey::new_unique();
|
let account_key2 = Pubkey::new_unique();
|
||||||
|
@ -10690,6 +10922,7 @@ pub mod tests {
|
||||||
&ClusterType::Development,
|
&ClusterType::Development,
|
||||||
AccountSecondaryIndexes::default(),
|
AccountSecondaryIndexes::default(),
|
||||||
caching_enabled,
|
caching_enabled,
|
||||||
|
AccountShrinkThreshold::default(),
|
||||||
);
|
);
|
||||||
db.load_delay = RACY_SLEEP_MS;
|
db.load_delay = RACY_SLEEP_MS;
|
||||||
let db = Arc::new(db);
|
let db = Arc::new(db);
|
||||||
|
@ -10761,6 +10994,7 @@ pub mod tests {
|
||||||
&ClusterType::Development,
|
&ClusterType::Development,
|
||||||
AccountSecondaryIndexes::default(),
|
AccountSecondaryIndexes::default(),
|
||||||
caching_enabled,
|
caching_enabled,
|
||||||
|
AccountShrinkThreshold::default(),
|
||||||
);
|
);
|
||||||
db.load_delay = RACY_SLEEP_MS;
|
db.load_delay = RACY_SLEEP_MS;
|
||||||
let db = Arc::new(db);
|
let db = Arc::new(db);
|
||||||
|
@ -10836,6 +11070,7 @@ pub mod tests {
|
||||||
&ClusterType::Development,
|
&ClusterType::Development,
|
||||||
AccountSecondaryIndexes::default(),
|
AccountSecondaryIndexes::default(),
|
||||||
caching_enabled,
|
caching_enabled,
|
||||||
|
AccountShrinkThreshold::default(),
|
||||||
);
|
);
|
||||||
let db = Arc::new(db);
|
let db = Arc::new(db);
|
||||||
let num_cached_slots = 100;
|
let num_cached_slots = 100;
|
||||||
|
@ -11108,4 +11343,34 @@ pub mod tests {
|
||||||
let stores = vec![Arc::new(s1), Arc::new(s2)];
|
let stores = vec![Arc::new(s1), Arc::new(s2)];
|
||||||
assert!(AccountsDb::is_shrinking_productive(0, &stores));
|
assert!(AccountsDb::is_shrinking_productive(0, &stores));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_is_candidate_for_shrink() {
|
||||||
|
solana_logger::setup();
|
||||||
|
|
||||||
|
let mut accounts = AccountsDb::new_single();
|
||||||
|
let dummy_path = Path::new("");
|
||||||
|
let dummy_size = 2 * PAGE_SIZE;
|
||||||
|
let entry = Arc::new(AccountStorageEntry::new(&dummy_path, 0, 1, dummy_size));
|
||||||
|
match accounts.shrink_ratio {
|
||||||
|
AccountShrinkThreshold::TotalSpace { shrink_ratio } => {
|
||||||
|
assert_eq!(
|
||||||
|
(DEFAULT_ACCOUNTS_SHRINK_RATIO * 100.) as u64,
|
||||||
|
(shrink_ratio * 100.) as u64
|
||||||
|
)
|
||||||
|
}
|
||||||
|
AccountShrinkThreshold::IndividalStore { shrink_ratio: _ } => {
|
||||||
|
panic!("Expect the default to be TotalSpace")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
entry.alive_bytes.store(3000, Ordering::Relaxed);
|
||||||
|
assert!(accounts.is_candidate_for_shrink(&entry));
|
||||||
|
entry.alive_bytes.store(5000, Ordering::Relaxed);
|
||||||
|
assert!(!accounts.is_candidate_for_shrink(&entry));
|
||||||
|
accounts.shrink_ratio = AccountShrinkThreshold::TotalSpace { shrink_ratio: 0.3 };
|
||||||
|
entry.alive_bytes.store(3000, Ordering::Relaxed);
|
||||||
|
assert!(accounts.is_candidate_for_shrink(&entry));
|
||||||
|
accounts.shrink_ratio = AccountShrinkThreshold::IndividalStore { shrink_ratio: 0.3 };
|
||||||
|
assert!(!accounts.is_candidate_for_shrink(&entry));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@ use crate::{
|
||||||
AccountAddressFilter, Accounts, TransactionAccountDeps, TransactionAccounts,
|
AccountAddressFilter, Accounts, TransactionAccountDeps, TransactionAccounts,
|
||||||
TransactionLoadResult, TransactionLoaders,
|
TransactionLoadResult, TransactionLoaders,
|
||||||
},
|
},
|
||||||
accounts_db::{ErrorCounters, SnapshotStorages},
|
accounts_db::{AccountShrinkThreshold, ErrorCounters, SnapshotStorages},
|
||||||
accounts_index::{AccountSecondaryIndexes, IndexKey},
|
accounts_index::{AccountSecondaryIndexes, IndexKey},
|
||||||
ancestors::{Ancestors, AncestorsForSerialization},
|
ancestors::{Ancestors, AncestorsForSerialization},
|
||||||
blockhash_queue::BlockhashQueue,
|
blockhash_queue::BlockhashQueue,
|
||||||
|
@ -1011,6 +1011,7 @@ impl Bank {
|
||||||
None,
|
None,
|
||||||
AccountSecondaryIndexes::default(),
|
AccountSecondaryIndexes::default(),
|
||||||
false,
|
false,
|
||||||
|
AccountShrinkThreshold::default(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1023,6 +1024,7 @@ impl Bank {
|
||||||
None,
|
None,
|
||||||
AccountSecondaryIndexes::default(),
|
AccountSecondaryIndexes::default(),
|
||||||
false,
|
false,
|
||||||
|
AccountShrinkThreshold::default(),
|
||||||
);
|
);
|
||||||
|
|
||||||
bank.ns_per_slot = std::u128::MAX;
|
bank.ns_per_slot = std::u128::MAX;
|
||||||
|
@ -1034,6 +1036,7 @@ impl Bank {
|
||||||
genesis_config: &GenesisConfig,
|
genesis_config: &GenesisConfig,
|
||||||
account_indexes: AccountSecondaryIndexes,
|
account_indexes: AccountSecondaryIndexes,
|
||||||
accounts_db_caching_enabled: bool,
|
accounts_db_caching_enabled: bool,
|
||||||
|
shrink_ratio: AccountShrinkThreshold,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self::new_with_paths(
|
Self::new_with_paths(
|
||||||
&genesis_config,
|
&genesis_config,
|
||||||
|
@ -1043,6 +1046,7 @@ impl Bank {
|
||||||
None,
|
None,
|
||||||
account_indexes,
|
account_indexes,
|
||||||
accounts_db_caching_enabled,
|
accounts_db_caching_enabled,
|
||||||
|
shrink_ratio,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1054,6 +1058,7 @@ impl Bank {
|
||||||
additional_builtins: Option<&Builtins>,
|
additional_builtins: Option<&Builtins>,
|
||||||
account_indexes: AccountSecondaryIndexes,
|
account_indexes: AccountSecondaryIndexes,
|
||||||
accounts_db_caching_enabled: bool,
|
accounts_db_caching_enabled: bool,
|
||||||
|
shrink_ratio: AccountShrinkThreshold,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mut bank = Self::default();
|
let mut bank = Self::default();
|
||||||
bank.ancestors = Ancestors::from(vec![bank.slot()]);
|
bank.ancestors = Ancestors::from(vec![bank.slot()]);
|
||||||
|
@ -1065,6 +1070,7 @@ impl Bank {
|
||||||
&genesis_config.cluster_type,
|
&genesis_config.cluster_type,
|
||||||
account_indexes,
|
account_indexes,
|
||||||
accounts_db_caching_enabled,
|
accounts_db_caching_enabled,
|
||||||
|
shrink_ratio,
|
||||||
));
|
));
|
||||||
bank.process_genesis_config(genesis_config);
|
bank.process_genesis_config(genesis_config);
|
||||||
bank.finish_init(genesis_config, additional_builtins);
|
bank.finish_init(genesis_config, additional_builtins);
|
||||||
|
@ -5292,7 +5298,7 @@ pub(crate) mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::{
|
use crate::{
|
||||||
accounts_background_service::{AbsRequestHandler, SendDroppedBankCallback},
|
accounts_background_service::{AbsRequestHandler, SendDroppedBankCallback},
|
||||||
accounts_db::SHRINK_RATIO,
|
accounts_db::DEFAULT_ACCOUNTS_SHRINK_RATIO,
|
||||||
accounts_index::{AccountIndex, AccountMap, AccountSecondaryIndexes, ITER_BATCH_SIZE},
|
accounts_index::{AccountIndex, AccountMap, AccountSecondaryIndexes, ITER_BATCH_SIZE},
|
||||||
ancestors::Ancestors,
|
ancestors::Ancestors,
|
||||||
genesis_utils::{
|
genesis_utils::{
|
||||||
|
@ -9195,6 +9201,7 @@ pub(crate) mod tests {
|
||||||
&genesis_config,
|
&genesis_config,
|
||||||
account_indexes,
|
account_indexes,
|
||||||
false,
|
false,
|
||||||
|
AccountShrinkThreshold::default(),
|
||||||
));
|
));
|
||||||
|
|
||||||
let address = Pubkey::new_unique();
|
let address = Pubkey::new_unique();
|
||||||
|
@ -10644,6 +10651,7 @@ pub(crate) mod tests {
|
||||||
&genesis_config,
|
&genesis_config,
|
||||||
AccountSecondaryIndexes::default(),
|
AccountSecondaryIndexes::default(),
|
||||||
false,
|
false,
|
||||||
|
AccountShrinkThreshold::default(),
|
||||||
));
|
));
|
||||||
bank0.restore_old_behavior_for_fragile_tests();
|
bank0.restore_old_behavior_for_fragile_tests();
|
||||||
goto_end_of_slot(Arc::<Bank>::get_mut(&mut bank0).unwrap());
|
goto_end_of_slot(Arc::<Bank>::get_mut(&mut bank0).unwrap());
|
||||||
|
@ -10655,11 +10663,13 @@ pub(crate) mod tests {
|
||||||
.accounts
|
.accounts
|
||||||
.scan_slot(0, |stored_account| Some(stored_account.stored_size()));
|
.scan_slot(0, |stored_account| Some(stored_account.stored_size()));
|
||||||
|
|
||||||
// Create an account such that it takes SHRINK_RATIO of the total account space for
|
// Create an account such that it takes DEFAULT_ACCOUNTS_SHRINK_RATIO of the total account space for
|
||||||
// the slot, so when it gets pruned, the storage entry will become a shrink candidate.
|
// the slot, so when it gets pruned, the storage entry will become a shrink candidate.
|
||||||
let bank0_total_size: usize = sizes.into_iter().sum();
|
let bank0_total_size: usize = sizes.into_iter().sum();
|
||||||
let pubkey0_size = (bank0_total_size as f64 / (1.0 - SHRINK_RATIO)).ceil();
|
let pubkey0_size = (bank0_total_size as f64 / (1.0 - DEFAULT_ACCOUNTS_SHRINK_RATIO)).ceil();
|
||||||
assert!(pubkey0_size / (pubkey0_size + bank0_total_size as f64) > SHRINK_RATIO);
|
assert!(
|
||||||
|
pubkey0_size / (pubkey0_size + bank0_total_size as f64) > DEFAULT_ACCOUNTS_SHRINK_RATIO
|
||||||
|
);
|
||||||
pubkey0_size as usize
|
pubkey0_size as usize
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10677,6 +10687,7 @@ pub(crate) mod tests {
|
||||||
&genesis_config,
|
&genesis_config,
|
||||||
AccountSecondaryIndexes::default(),
|
AccountSecondaryIndexes::default(),
|
||||||
true,
|
true,
|
||||||
|
AccountShrinkThreshold::default(),
|
||||||
));
|
));
|
||||||
bank0.restore_old_behavior_for_fragile_tests();
|
bank0.restore_old_behavior_for_fragile_tests();
|
||||||
|
|
||||||
|
@ -11896,6 +11907,7 @@ pub(crate) mod tests {
|
||||||
&genesis_config,
|
&genesis_config,
|
||||||
AccountSecondaryIndexes::default(),
|
AccountSecondaryIndexes::default(),
|
||||||
accounts_db_caching_enabled,
|
accounts_db_caching_enabled,
|
||||||
|
AccountShrinkThreshold::default(),
|
||||||
));
|
));
|
||||||
bank0.set_callback(drop_callback);
|
bank0.set_callback(drop_callback);
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
accounts::Accounts,
|
accounts::Accounts,
|
||||||
accounts_db::{AccountStorageEntry, AccountsDb, AppendVecId, BankHashInfo},
|
accounts_db::{
|
||||||
|
AccountShrinkThreshold, AccountStorageEntry, AccountsDb, AppendVecId, BankHashInfo,
|
||||||
|
},
|
||||||
accounts_index::AccountSecondaryIndexes,
|
accounts_index::AccountSecondaryIndexes,
|
||||||
ancestors::Ancestors,
|
ancestors::Ancestors,
|
||||||
append_vec::{AppendVec, StoredMetaWriteVersion},
|
append_vec::{AppendVec, StoredMetaWriteVersion},
|
||||||
|
@ -136,6 +138,7 @@ pub(crate) fn bank_from_stream<R>(
|
||||||
account_indexes: AccountSecondaryIndexes,
|
account_indexes: AccountSecondaryIndexes,
|
||||||
caching_enabled: bool,
|
caching_enabled: bool,
|
||||||
limit_load_slot_count_from_snapshot: Option<usize>,
|
limit_load_slot_count_from_snapshot: Option<usize>,
|
||||||
|
shrink_ratio: AccountShrinkThreshold,
|
||||||
) -> std::result::Result<Bank, Error>
|
) -> std::result::Result<Bank, Error>
|
||||||
where
|
where
|
||||||
R: Read,
|
R: Read,
|
||||||
|
@ -156,6 +159,7 @@ where
|
||||||
account_indexes,
|
account_indexes,
|
||||||
caching_enabled,
|
caching_enabled,
|
||||||
limit_load_slot_count_from_snapshot,
|
limit_load_slot_count_from_snapshot,
|
||||||
|
shrink_ratio,
|
||||||
)?;
|
)?;
|
||||||
Ok(bank)
|
Ok(bank)
|
||||||
}};
|
}};
|
||||||
|
@ -246,6 +250,7 @@ fn reconstruct_bank_from_fields<E>(
|
||||||
account_indexes: AccountSecondaryIndexes,
|
account_indexes: AccountSecondaryIndexes,
|
||||||
caching_enabled: bool,
|
caching_enabled: bool,
|
||||||
limit_load_slot_count_from_snapshot: Option<usize>,
|
limit_load_slot_count_from_snapshot: Option<usize>,
|
||||||
|
shrink_ratio: AccountShrinkThreshold,
|
||||||
) -> Result<Bank, Error>
|
) -> Result<Bank, Error>
|
||||||
where
|
where
|
||||||
E: SerializableStorage,
|
E: SerializableStorage,
|
||||||
|
@ -258,6 +263,7 @@ where
|
||||||
account_indexes,
|
account_indexes,
|
||||||
caching_enabled,
|
caching_enabled,
|
||||||
limit_load_slot_count_from_snapshot,
|
limit_load_slot_count_from_snapshot,
|
||||||
|
shrink_ratio,
|
||||||
)?;
|
)?;
|
||||||
accounts_db.freeze_accounts(
|
accounts_db.freeze_accounts(
|
||||||
&Ancestors::from(&bank_fields.ancestors),
|
&Ancestors::from(&bank_fields.ancestors),
|
||||||
|
@ -284,6 +290,7 @@ fn reconstruct_accountsdb_from_fields<E>(
|
||||||
account_indexes: AccountSecondaryIndexes,
|
account_indexes: AccountSecondaryIndexes,
|
||||||
caching_enabled: bool,
|
caching_enabled: bool,
|
||||||
limit_load_slot_count_from_snapshot: Option<usize>,
|
limit_load_slot_count_from_snapshot: Option<usize>,
|
||||||
|
shrink_ratio: AccountShrinkThreshold,
|
||||||
) -> Result<AccountsDb, Error>
|
) -> Result<AccountsDb, Error>
|
||||||
where
|
where
|
||||||
E: SerializableStorage,
|
E: SerializableStorage,
|
||||||
|
@ -293,6 +300,7 @@ where
|
||||||
cluster_type,
|
cluster_type,
|
||||||
account_indexes,
|
account_indexes,
|
||||||
caching_enabled,
|
caching_enabled,
|
||||||
|
shrink_ratio,
|
||||||
);
|
);
|
||||||
let AccountsDbFields(storage, version, slot, bank_hash_info) = accounts_db_fields;
|
let AccountsDbFields(storage, version, slot, bank_hash_info) = accounts_db_fields;
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ use {
|
||||||
super::*,
|
super::*,
|
||||||
crate::{
|
crate::{
|
||||||
accounts::{create_test_accounts, Accounts},
|
accounts::{create_test_accounts, Accounts},
|
||||||
accounts_db::get_temp_accounts_paths,
|
accounts_db::{get_temp_accounts_paths, AccountShrinkThreshold},
|
||||||
bank::{Bank, StatusCacheRc},
|
bank::{Bank, StatusCacheRc},
|
||||||
hardened_unpack::UnpackedAppendVecMap,
|
hardened_unpack::UnpackedAppendVecMap,
|
||||||
},
|
},
|
||||||
|
@ -74,6 +74,7 @@ where
|
||||||
AccountSecondaryIndexes::default(),
|
AccountSecondaryIndexes::default(),
|
||||||
false,
|
false,
|
||||||
None,
|
None,
|
||||||
|
AccountShrinkThreshold::default(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,6 +130,7 @@ fn test_accounts_serialize_style(serde_style: SerdeStyle) {
|
||||||
&ClusterType::Development,
|
&ClusterType::Development,
|
||||||
AccountSecondaryIndexes::default(),
|
AccountSecondaryIndexes::default(),
|
||||||
false,
|
false,
|
||||||
|
AccountShrinkThreshold::default(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut pubkeys: Vec<Pubkey> = vec![];
|
let mut pubkeys: Vec<Pubkey> = vec![];
|
||||||
|
@ -228,6 +230,7 @@ fn test_bank_serialize_style(serde_style: SerdeStyle) {
|
||||||
AccountSecondaryIndexes::default(),
|
AccountSecondaryIndexes::default(),
|
||||||
false,
|
false,
|
||||||
None,
|
None,
|
||||||
|
AccountShrinkThreshold::default(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
dbank.src = ref_sc;
|
dbank.src = ref_sc;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
accounts_db::AccountsDb,
|
accounts_db::{AccountShrinkThreshold, AccountsDb},
|
||||||
accounts_index::AccountSecondaryIndexes,
|
accounts_index::AccountSecondaryIndexes,
|
||||||
bank::{Bank, BankSlotDelta, Builtins},
|
bank::{Bank, BankSlotDelta, Builtins},
|
||||||
bank_forks::ArchiveFormat,
|
bank_forks::ArchiveFormat,
|
||||||
|
@ -605,6 +605,7 @@ pub fn bank_from_archive<P: AsRef<Path>>(
|
||||||
account_indexes: AccountSecondaryIndexes,
|
account_indexes: AccountSecondaryIndexes,
|
||||||
accounts_db_caching_enabled: bool,
|
accounts_db_caching_enabled: bool,
|
||||||
limit_load_slot_count_from_snapshot: Option<usize>,
|
limit_load_slot_count_from_snapshot: Option<usize>,
|
||||||
|
shrink_ratio: AccountShrinkThreshold,
|
||||||
) -> Result<Bank> {
|
) -> Result<Bank> {
|
||||||
let unpack_dir = tempfile::Builder::new()
|
let unpack_dir = tempfile::Builder::new()
|
||||||
.prefix(TMP_SNAPSHOT_PREFIX)
|
.prefix(TMP_SNAPSHOT_PREFIX)
|
||||||
|
@ -636,6 +637,7 @@ pub fn bank_from_archive<P: AsRef<Path>>(
|
||||||
account_indexes,
|
account_indexes,
|
||||||
accounts_db_caching_enabled,
|
accounts_db_caching_enabled,
|
||||||
limit_load_slot_count_from_snapshot,
|
limit_load_slot_count_from_snapshot,
|
||||||
|
shrink_ratio,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
if !bank.verify_snapshot_bank() {
|
if !bank.verify_snapshot_bank() {
|
||||||
|
@ -796,6 +798,7 @@ fn rebuild_bank_from_snapshots(
|
||||||
account_indexes: AccountSecondaryIndexes,
|
account_indexes: AccountSecondaryIndexes,
|
||||||
accounts_db_caching_enabled: bool,
|
accounts_db_caching_enabled: bool,
|
||||||
limit_load_slot_count_from_snapshot: Option<usize>,
|
limit_load_slot_count_from_snapshot: Option<usize>,
|
||||||
|
shrink_ratio: AccountShrinkThreshold,
|
||||||
) -> Result<Bank> {
|
) -> Result<Bank> {
|
||||||
info!("snapshot version: {}", snapshot_version);
|
info!("snapshot version: {}", snapshot_version);
|
||||||
|
|
||||||
|
@ -832,6 +835,7 @@ fn rebuild_bank_from_snapshots(
|
||||||
account_indexes,
|
account_indexes,
|
||||||
accounts_db_caching_enabled,
|
accounts_db_caching_enabled,
|
||||||
limit_load_slot_count_from_snapshot,
|
limit_load_slot_count_from_snapshot,
|
||||||
|
shrink_ratio,
|
||||||
),
|
),
|
||||||
}?)
|
}?)
|
||||||
})?;
|
})?;
|
||||||
|
|
|
@ -39,6 +39,10 @@ use {
|
||||||
solana_poh::poh_service,
|
solana_poh::poh_service,
|
||||||
solana_rpc::{rpc::JsonRpcConfig, rpc_pubsub_service::PubSubConfig},
|
solana_rpc::{rpc::JsonRpcConfig, rpc_pubsub_service::PubSubConfig},
|
||||||
solana_runtime::{
|
solana_runtime::{
|
||||||
|
accounts_db::{
|
||||||
|
AccountShrinkThreshold, DEFAULT_ACCOUNTS_SHRINK_OPTIMIZE_TOTAL_SPACE,
|
||||||
|
DEFAULT_ACCOUNTS_SHRINK_RATIO,
|
||||||
|
},
|
||||||
accounts_index::{
|
accounts_index::{
|
||||||
AccountIndex, AccountSecondaryIndexes, AccountSecondaryIndexesIncludeExclude,
|
AccountIndex, AccountSecondaryIndexes, AccountSecondaryIndexesIncludeExclude,
|
||||||
},
|
},
|
||||||
|
@ -1009,6 +1013,9 @@ pub fn main() {
|
||||||
let default_max_snapshot_to_retain = &DEFAULT_MAX_SNAPSHOTS_TO_RETAIN.to_string();
|
let default_max_snapshot_to_retain = &DEFAULT_MAX_SNAPSHOTS_TO_RETAIN.to_string();
|
||||||
let default_min_snapshot_download_speed = &DEFAULT_MIN_SNAPSHOT_DOWNLOAD_SPEED.to_string();
|
let default_min_snapshot_download_speed = &DEFAULT_MIN_SNAPSHOT_DOWNLOAD_SPEED.to_string();
|
||||||
let default_max_snapshot_download_abort = &MAX_SNAPSHOT_DOWNLOAD_ABORT.to_string();
|
let default_max_snapshot_download_abort = &MAX_SNAPSHOT_DOWNLOAD_ABORT.to_string();
|
||||||
|
let default_accounts_shrink_optimize_total_space =
|
||||||
|
&DEFAULT_ACCOUNTS_SHRINK_OPTIMIZE_TOTAL_SPACE.to_string();
|
||||||
|
let default_accounts_shrink_ratio = &DEFAULT_ACCOUNTS_SHRINK_RATIO.to_string();
|
||||||
|
|
||||||
let matches = App::new(crate_name!()).about(crate_description!())
|
let matches = App::new(crate_name!()).about(crate_description!())
|
||||||
.version(solana_version::version!())
|
.version(solana_version::version!())
|
||||||
|
@ -1777,6 +1784,29 @@ pub fn main() {
|
||||||
.conflicts_with("no_accounts_db_caching")
|
.conflicts_with("no_accounts_db_caching")
|
||||||
.hidden(true)
|
.hidden(true)
|
||||||
)
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("accounts_shrink_optimize_total_space")
|
||||||
|
.long("accounts-shrink-optimize-total-space")
|
||||||
|
.takes_value(true)
|
||||||
|
.value_name("BOOLEAN")
|
||||||
|
.default_value(default_accounts_shrink_optimize_total_space)
|
||||||
|
.help("When this is set to true, the system will shrink the most \
|
||||||
|
sparse accounts and when the overall shrink ratio is above \
|
||||||
|
the specified accounts-shrink-ratio, the shrink will stop and \
|
||||||
|
it will skip all other less sparse accounts."),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("accounts_shrink_ratio")
|
||||||
|
.long("accounts-shrink-ratio")
|
||||||
|
.takes_value(true)
|
||||||
|
.value_name("RATIO")
|
||||||
|
.default_value(default_accounts_shrink_ratio)
|
||||||
|
.help("Specifies the shrink ratio for the accounts to be shrunk. \
|
||||||
|
The shrink ratio is defined as the ratio of the bytes alive over the \
|
||||||
|
total bytes used. If the account's shrink ratio is less than this ratio \
|
||||||
|
it becomes a candidate for shrinking. The value must between 0. and 1.0 \
|
||||||
|
inclusive."),
|
||||||
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("no_duplicate_instance_check")
|
Arg::with_name("no_duplicate_instance_check")
|
||||||
.long("no-duplicate-instance-check")
|
.long("no-duplicate-instance-check")
|
||||||
|
@ -2075,6 +2105,23 @@ pub fn main() {
|
||||||
let account_indexes = process_account_indexes(&matches);
|
let account_indexes = process_account_indexes(&matches);
|
||||||
|
|
||||||
let restricted_repair_only_mode = matches.is_present("restricted_repair_only_mode");
|
let restricted_repair_only_mode = matches.is_present("restricted_repair_only_mode");
|
||||||
|
let accounts_shrink_optimize_total_space =
|
||||||
|
value_t_or_exit!(matches, "accounts_shrink_optimize_total_space", bool);
|
||||||
|
let shrink_ratio = value_t_or_exit!(matches, "accounts_shrink_ratio", f64);
|
||||||
|
if !(0.0..=1.0).contains(&shrink_ratio) {
|
||||||
|
eprintln!(
|
||||||
|
"The specified account-shrink-ratio is invalid, it must be between 0. and 1.0 inclusive: {}",
|
||||||
|
shrink_ratio
|
||||||
|
);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
let accounts_shrink_ratio = if accounts_shrink_optimize_total_space {
|
||||||
|
AccountShrinkThreshold::TotalSpace { shrink_ratio }
|
||||||
|
} else {
|
||||||
|
AccountShrinkThreshold::IndividalStore { shrink_ratio }
|
||||||
|
};
|
||||||
|
|
||||||
let mut validator_config = ValidatorConfig {
|
let mut validator_config = ValidatorConfig {
|
||||||
require_tower: matches.is_present("require_tower"),
|
require_tower: matches.is_present("require_tower"),
|
||||||
tower_path: value_t!(matches, "tower", PathBuf).ok(),
|
tower_path: value_t!(matches, "tower", PathBuf).ok(),
|
||||||
|
@ -2172,6 +2219,7 @@ pub fn main() {
|
||||||
accounts_db_use_index_hash_calculation: matches.is_present("accounts_db_index_hashing"),
|
accounts_db_use_index_hash_calculation: matches.is_present("accounts_db_index_hashing"),
|
||||||
tpu_coalesce_ms,
|
tpu_coalesce_ms,
|
||||||
no_wait_for_vote_to_start_leader: matches.is_present("no_wait_for_vote_to_start_leader"),
|
no_wait_for_vote_to_start_leader: matches.is_present("no_wait_for_vote_to_start_leader"),
|
||||||
|
accounts_shrink_ratio,
|
||||||
..ValidatorConfig::default()
|
..ValidatorConfig::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue