From de1940fd5891f760fa7c369c50d8927a5410f1c9 Mon Sep 17 00:00:00 2001 From: HaoranYi <219428+HaoranYi@users.noreply.github.com> Date: Tue, 22 Oct 2024 15:21:09 -0500 Subject: [PATCH] clean all zero storages at index generation time (#3196) * clean all zero storeage at index gen time * add stats * wait to add zero slot to clean after index flush * pr * remove log * fix rebase --------- Co-authored-by: HaoranYi --- accounts-db/src/accounts_db.rs | 42 ++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/accounts-db/src/accounts_db.rs b/accounts-db/src/accounts_db.rs index e6601cb983d043..8f30d018bc53d6 100644 --- a/accounts-db/src/accounts_db.rs +++ b/accounts-db/src/accounts_db.rs @@ -671,6 +671,7 @@ struct SlotIndexGenerationInfo { accounts_data_len: u64, amount_to_top_off_rent: u64, rent_paying_accounts_by_partition: Vec, + all_accounts_are_zero_lamports: bool, } /// The lt hash of old/duplicate accounts @@ -710,6 +711,7 @@ struct GenerateIndexTimings { pub total_slots: u64, pub slots_to_clean: u64, pub par_duplicates_lt_hash_us: AtomicU64, + pub all_accounts_are_zero_lamports_slots: u64, } #[derive(Default, Debug, PartialEq, Eq)] @@ -791,6 +793,11 @@ impl GenerateIndexTimings { self.par_duplicates_lt_hash_us.load(Ordering::Relaxed), i64 ), + ( + "all_accounts_are_zero_lamports_slots", + self.all_accounts_are_zero_lamports_slots, + i64 + ), ); } } @@ -8317,6 +8324,7 @@ impl AccountsDb { let mut num_accounts_rent_paying = 0; let mut amount_to_top_off_rent = 0; let mut stored_size_alive = 0; + let mut all_accounts_are_zero_lamports = true; let (dirty_pubkeys, insert_time_us, mut generate_index_results) = { let mut items_local = Vec::default(); @@ -8324,9 +8332,11 @@ impl AccountsDb { stored_size_alive += info.stored_size_aligned; if info.index_info.lamports > 0 { accounts_data_len += info.index_info.data_len; + all_accounts_are_zero_lamports = false; } items_local.push(info.index_info); }); + let items_len = items_local.len(); let items = items_local.into_iter().map(|info| { if let Some(amount_to_top_off_rent_this_account) = Self::stats_for_rent_payers( @@ -8407,6 +8417,7 @@ impl AccountsDb { accounts_data_len, amount_to_top_off_rent, rent_paying_accounts_by_partition, + all_accounts_are_zero_lamports, } } @@ -8461,6 +8472,8 @@ impl AccountsDb { let rent_paying = AtomicUsize::new(0); let amount_to_top_off_rent = AtomicU64::new(0); let total_including_duplicates = AtomicU64::new(0); + let all_accounts_are_zero_lamports_slots = AtomicU64::new(0); + let mut all_zeros_slots = Mutex::new(Vec::<(Slot, Arc)>::new()); let scan_time: u64 = slots .par_chunks(chunk_size) .map(|slots| { @@ -8470,6 +8483,8 @@ impl AccountsDb { outer_slots_len as u64, ); let mut scan_time_sum = 0; + let mut all_accounts_are_zero_lamports_slots_inner = 0; + let mut all_zeros_slots_inner = vec![]; let mut insert_time_sum = 0; let mut total_including_duplicates_sum = 0; let mut accounts_data_len_sum = 0; @@ -8496,6 +8511,7 @@ impl AccountsDb { amount_to_top_off_rent: amount_to_top_off_rent_this_slot, rent_paying_accounts_by_partition: rent_paying_accounts_by_partition_this_slot, + all_accounts_are_zero_lamports, } = self.generate_index_for_slot( &storage, *slot, @@ -8519,6 +8535,11 @@ impl AccountsDb { } total_including_duplicates_sum += total_this_slot; accounts_data_len_sum += accounts_data_len_this_slot; + if all_accounts_are_zero_lamports { + all_accounts_are_zero_lamports_slots_inner += 1; + all_zeros_slots_inner.push((*slot, Arc::clone(&storage))); + } + insert_us } else { // verify index matches expected and measure the time to get all items @@ -8549,6 +8570,14 @@ impl AccountsDb { }; insert_time_sum += insert_us; } + all_accounts_are_zero_lamports_slots.fetch_add( + all_accounts_are_zero_lamports_slots_inner, + Ordering::Relaxed, + ); + all_zeros_slots + .lock() + .unwrap() + .append(&mut all_zeros_slots_inner); insertion_time_us.fetch_add(insert_time_sum, Ordering::Relaxed); total_including_duplicates .fetch_add(total_including_duplicates_sum, Ordering::Relaxed); @@ -8636,6 +8665,8 @@ impl AccountsDb { populate_duplicate_keys_us, total_including_duplicates: total_including_duplicates.load(Ordering::Relaxed), total_slots: slots.len() as u64, + all_accounts_are_zero_lamports_slots: all_accounts_are_zero_lamports_slots + .load(Ordering::Relaxed), ..GenerateIndexTimings::default() }; @@ -8727,6 +8758,17 @@ impl AccountsDb { "accounts data len: {}", accounts_data_len.load(Ordering::Relaxed) ); + + // insert all zero lamport account storage into the dirty stores and add them into the uncleaned roots for clean to pick up + let all_zero_slots_to_clean = std::mem::take(all_zeros_slots.get_mut().unwrap()); + info!( + "insert all zero slots to clean at startup {}", + all_zero_slots_to_clean.len() + ); + for (slot, storage) in all_zero_slots_to_clean { + self.dirty_stores.insert(slot, storage); + self.accounts_index.add_uncleaned_roots([slot]); + } } if pass == 0 {