add metrics on rent collection pieces (#25713)
This commit is contained in:
parent
d1a6cebaa2
commit
96f71c7d4d
|
@ -191,6 +191,15 @@ pub const MAX_LEADER_SCHEDULE_STAKES: Epoch = 5;
|
||||||
|
|
||||||
pub type Rewrites = RwLock<HashMap<Pubkey, Hash>>;
|
pub type Rewrites = RwLock<HashMap<Pubkey, Hash>>;
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
struct RentMetrics {
|
||||||
|
hold_range_us: AtomicU64,
|
||||||
|
load_us: AtomicU64,
|
||||||
|
collect_us: AtomicU64,
|
||||||
|
hash_us: AtomicU64,
|
||||||
|
store_us: AtomicU64,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
pub struct RentDebit {
|
pub struct RentDebit {
|
||||||
rent_collected: u64,
|
rent_collected: u64,
|
||||||
|
@ -5173,9 +5182,12 @@ impl Bank {
|
||||||
let mut measure = Measure::start("collect_rent_eagerly-ms");
|
let mut measure = Measure::start("collect_rent_eagerly-ms");
|
||||||
let partitions = self.rent_collection_partitions();
|
let partitions = self.rent_collection_partitions();
|
||||||
let count = partitions.len();
|
let count = partitions.len();
|
||||||
|
let rent_metrics = RentMetrics::default();
|
||||||
let account_count: usize = partitions
|
let account_count: usize = partitions
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|partition| self.collect_rent_in_partition(partition, just_rewrites))
|
.map(|partition| {
|
||||||
|
self.collect_rent_in_partition(partition, just_rewrites, &rent_metrics)
|
||||||
|
})
|
||||||
.sum();
|
.sum();
|
||||||
measure.stop();
|
measure.stop();
|
||||||
datapoint_info!(
|
datapoint_info!(
|
||||||
|
@ -5188,6 +5200,15 @@ impl Bank {
|
||||||
i64
|
i64
|
||||||
),
|
),
|
||||||
("total_time_us", measure.as_us(), i64),
|
("total_time_us", measure.as_us(), i64),
|
||||||
|
(
|
||||||
|
"hold_range_us",
|
||||||
|
rent_metrics.hold_range_us.load(Relaxed),
|
||||||
|
i64
|
||||||
|
),
|
||||||
|
("load_us", rent_metrics.load_us.load(Relaxed), i64),
|
||||||
|
("collect_us", rent_metrics.collect_us.load(Relaxed), i64),
|
||||||
|
("hash_us", rent_metrics.hash_us.load(Relaxed), i64),
|
||||||
|
("store_us", rent_metrics.store_us.load(Relaxed), i64),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5222,33 +5243,49 @@ impl Bank {
|
||||||
/// update bank's rewrites set for all rewrites that were skipped
|
/// update bank's rewrites set for all rewrites that were skipped
|
||||||
/// if 'just_rewrites', function will only update bank's rewrites set and not actually store any accounts
|
/// if 'just_rewrites', function will only update bank's rewrites set and not actually store any accounts
|
||||||
/// return # accounts loaded
|
/// return # accounts loaded
|
||||||
fn collect_rent_in_partition(&self, partition: Partition, just_rewrites: bool) -> usize {
|
fn collect_rent_in_partition(
|
||||||
|
&self,
|
||||||
|
partition: Partition,
|
||||||
|
just_rewrites: bool,
|
||||||
|
metrics: &RentMetrics,
|
||||||
|
) -> usize {
|
||||||
let subrange = Self::pubkey_range_from_partition(partition);
|
let subrange = Self::pubkey_range_from_partition(partition);
|
||||||
|
|
||||||
|
let mut hold_range = Measure::start("hold_range");
|
||||||
let thread_pool = &self.rc.accounts.accounts_db.thread_pool;
|
let thread_pool = &self.rc.accounts.accounts_db.thread_pool;
|
||||||
self.rc
|
self.rc
|
||||||
.accounts
|
.accounts
|
||||||
.hold_range_in_memory(&subrange, true, thread_pool);
|
.hold_range_in_memory(&subrange, true, thread_pool);
|
||||||
|
hold_range.stop();
|
||||||
|
|
||||||
|
let mut load = Measure::start("load");
|
||||||
let accounts = self
|
let accounts = self
|
||||||
.rc
|
.rc
|
||||||
.accounts
|
.accounts
|
||||||
.load_to_collect_rent_eagerly(&self.ancestors, subrange.clone());
|
.load_to_collect_rent_eagerly(&self.ancestors, subrange.clone());
|
||||||
let account_count = accounts.len();
|
let account_count = accounts.len();
|
||||||
|
load.stop();
|
||||||
|
metrics.load_us.fetch_add(load.as_us(), Relaxed);
|
||||||
|
|
||||||
// parallelize?
|
// parallelize?
|
||||||
let mut rent_debits = RentDebits::default();
|
let mut rent_debits = RentDebits::default();
|
||||||
let mut total_collected = CollectedInfo::default();
|
let mut total_collected = CollectedInfo::default();
|
||||||
let bank_slot = self.slot();
|
let bank_slot = self.slot();
|
||||||
let mut rewrites_skipped = Vec::with_capacity(accounts.len());
|
let mut rewrites_skipped = Vec::with_capacity(accounts.len());
|
||||||
|
let mut collect_us = 0;
|
||||||
|
let mut hash_skipped_rewrites_us = 0;
|
||||||
|
let mut store_us = 0;
|
||||||
let can_skip_rewrites = self.rc.accounts.accounts_db.skip_rewrites || just_rewrites;
|
let can_skip_rewrites = self.rc.accounts.accounts_db.skip_rewrites || just_rewrites;
|
||||||
for (pubkey, mut account, loaded_slot) in accounts {
|
for (pubkey, mut account, loaded_slot) in accounts {
|
||||||
let old_rent_epoch = account.rent_epoch();
|
let old_rent_epoch = account.rent_epoch();
|
||||||
|
let mut time = Measure::start("collect");
|
||||||
let collected = self.rent_collector.collect_from_existing_account(
|
let collected = self.rent_collector.collect_from_existing_account(
|
||||||
&pubkey,
|
&pubkey,
|
||||||
&mut account,
|
&mut account,
|
||||||
self.rc.accounts.accounts_db.filler_account_suffix.as_ref(),
|
self.rc.accounts.accounts_db.filler_account_suffix.as_ref(),
|
||||||
);
|
);
|
||||||
|
time.stop();
|
||||||
|
collect_us += time.as_us();
|
||||||
// only store accounts where we collected rent
|
// only store accounts where we collected rent
|
||||||
// but get the hash for all these accounts even if collected rent is 0 (= not updated).
|
// but get the hash for all these accounts even if collected rent is 0 (= not updated).
|
||||||
// Also, there's another subtle side-effect from this: this
|
// Also, there's another subtle side-effect from this: this
|
||||||
|
@ -5266,16 +5303,27 @@ impl Bank {
|
||||||
// this would have been rewritten previously. Now we skip it.
|
// this would have been rewritten previously. Now we skip it.
|
||||||
// calculate the hash that we would have gotten if we did the rewrite.
|
// calculate the hash that we would have gotten if we did the rewrite.
|
||||||
// This will be needed to calculate the bank's hash.
|
// This will be needed to calculate the bank's hash.
|
||||||
|
let mut time = Measure::start("hash_account");
|
||||||
let hash =
|
let hash =
|
||||||
crate::accounts_db::AccountsDb::hash_account(self.slot(), &account, &pubkey);
|
crate::accounts_db::AccountsDb::hash_account(self.slot(), &account, &pubkey);
|
||||||
|
time.stop();
|
||||||
|
hash_skipped_rewrites_us += time.as_us();
|
||||||
rewrites_skipped.push((pubkey, hash));
|
rewrites_skipped.push((pubkey, hash));
|
||||||
assert_eq!(collected, CollectedInfo::default());
|
assert_eq!(collected, CollectedInfo::default());
|
||||||
} else if !just_rewrites {
|
} else if !just_rewrites {
|
||||||
|
let mut time = Measure::start("store_account");
|
||||||
total_collected += collected;
|
total_collected += collected;
|
||||||
self.store_account(&pubkey, &account);
|
self.store_account(&pubkey, &account);
|
||||||
|
time.stop();
|
||||||
|
store_us += time.as_us();
|
||||||
}
|
}
|
||||||
rent_debits.insert(&pubkey, collected.rent_amount, account.lamports());
|
rent_debits.insert(&pubkey, collected.rent_amount, account.lamports());
|
||||||
}
|
}
|
||||||
|
metrics.hold_range_us.fetch_add(hold_range.as_us(), Relaxed);
|
||||||
|
metrics.collect_us.fetch_add(collect_us, Relaxed);
|
||||||
|
metrics.hash_us.fetch_add(hash_skipped_rewrites_us, Relaxed);
|
||||||
|
metrics.store_us.fetch_add(store_us, Relaxed);
|
||||||
|
|
||||||
self.remember_skipped_rewrites(rewrites_skipped);
|
self.remember_skipped_rewrites(rewrites_skipped);
|
||||||
self.collected_rent
|
self.collected_rent
|
||||||
.fetch_add(total_collected.rent_amount, Relaxed);
|
.fetch_add(total_collected.rent_amount, Relaxed);
|
||||||
|
@ -9383,7 +9431,7 @@ pub(crate) mod tests {
|
||||||
|
|
||||||
assert_eq!(bank.collected_rent.load(Relaxed), 0);
|
assert_eq!(bank.collected_rent.load(Relaxed), 0);
|
||||||
assert!(bank.rewrites_skipped_this_slot.read().unwrap().is_empty());
|
assert!(bank.rewrites_skipped_this_slot.read().unwrap().is_empty());
|
||||||
bank.collect_rent_in_partition((0, 0, 1), true);
|
bank.collect_rent_in_partition((0, 0, 1), true, &RentMetrics::default());
|
||||||
{
|
{
|
||||||
let rewrites_skipped = bank.rewrites_skipped_this_slot.read().unwrap();
|
let rewrites_skipped = bank.rewrites_skipped_this_slot.read().unwrap();
|
||||||
// `rewrites_skipped.len()` is the number of non-rent paying accounts in the slot. This
|
// `rewrites_skipped.len()` is the number of non-rent paying accounts in the slot. This
|
||||||
|
@ -9405,7 +9453,7 @@ pub(crate) mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_eq!(bank.collected_rent.load(Relaxed), 0);
|
assert_eq!(bank.collected_rent.load(Relaxed), 0);
|
||||||
bank.collect_rent_in_partition((0, 0, 1), false); // all range
|
bank.collect_rent_in_partition((0, 0, 1), false, &RentMetrics::default()); // all range
|
||||||
|
|
||||||
assert_eq!(bank.collected_rent.load(Relaxed), rent_collected);
|
assert_eq!(bank.collected_rent.load(Relaxed), rent_collected);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -9488,8 +9536,8 @@ pub(crate) mod tests {
|
||||||
assert_eq!(hash1_with_zero, hash1_without_zero);
|
assert_eq!(hash1_with_zero, hash1_without_zero);
|
||||||
assert_ne!(hash1_with_zero, Hash::default());
|
assert_ne!(hash1_with_zero, Hash::default());
|
||||||
|
|
||||||
bank2_with_zero.collect_rent_in_partition((0, 0, 1), false); // all
|
bank2_with_zero.collect_rent_in_partition((0, 0, 1), false, &RentMetrics::default()); // all
|
||||||
bank2_without_zero.collect_rent_in_partition((0, 0, 1), false); // all
|
bank2_without_zero.collect_rent_in_partition((0, 0, 1), false, &RentMetrics::default()); // all
|
||||||
|
|
||||||
bank2_with_zero.freeze();
|
bank2_with_zero.freeze();
|
||||||
let hash2_with_zero = bank2_with_zero.hash();
|
let hash2_with_zero = bank2_with_zero.hash();
|
||||||
|
|
Loading…
Reference in New Issue