Fix repair for a range of slots (#4286)
* Fix repair for a range of slots * Delete RepairInfo
This commit is contained in:
@ -39,21 +39,6 @@ pub enum RepairType {
|
|||||||
Blob(u64, u64),
|
Blob(u64, u64),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
struct RepairInfo {
|
|
||||||
max_slot: u64,
|
|
||||||
repair_tries: u64,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RepairInfo {
|
|
||||||
fn new() -> Self {
|
|
||||||
RepairInfo {
|
|
||||||
max_slot: 0,
|
|
||||||
repair_tries: 0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct RepairSlotRange {
|
pub struct RepairSlotRange {
|
||||||
pub start: u64,
|
pub start: u64,
|
||||||
pub end: u64,
|
pub end: u64,
|
||||||
@ -104,7 +89,6 @@ impl RepairService {
|
|||||||
cluster_info: &Arc<RwLock<ClusterInfo>>,
|
cluster_info: &Arc<RwLock<ClusterInfo>>,
|
||||||
repair_strategy: RepairStrategy,
|
repair_strategy: RepairStrategy,
|
||||||
) {
|
) {
|
||||||
let mut repair_info = RepairInfo::new();
|
|
||||||
let mut epoch_slots: HashSet<u64> = HashSet::new();
|
let mut epoch_slots: HashSet<u64> = HashSet::new();
|
||||||
let id = cluster_info.read().unwrap().id();
|
let id = cluster_info.read().unwrap().id();
|
||||||
if let RepairStrategy::RepairAll {
|
if let RepairStrategy::RepairAll {
|
||||||
@ -135,7 +119,6 @@ impl RepairService {
|
|||||||
Self::generate_repairs_in_range(
|
Self::generate_repairs_in_range(
|
||||||
blocktree,
|
blocktree,
|
||||||
MAX_REPAIR_LENGTH,
|
MAX_REPAIR_LENGTH,
|
||||||
&mut repair_info,
|
|
||||||
repair_slot_range,
|
repair_slot_range,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -195,46 +178,30 @@ impl RepairService {
|
|||||||
fn generate_repairs_in_range(
|
fn generate_repairs_in_range(
|
||||||
blocktree: &Blocktree,
|
blocktree: &Blocktree,
|
||||||
max_repairs: usize,
|
max_repairs: usize,
|
||||||
repair_info: &mut RepairInfo,
|
|
||||||
repair_range: &RepairSlotRange,
|
repair_range: &RepairSlotRange,
|
||||||
) -> Result<(Vec<RepairType>)> {
|
) -> Result<(Vec<RepairType>)> {
|
||||||
// Slot height and blob indexes for blobs we want to repair
|
// Slot height and blob indexes for blobs we want to repair
|
||||||
let mut repairs: Vec<RepairType> = vec![];
|
let mut repairs: Vec<RepairType> = vec![];
|
||||||
let mut meta_iter = blocktree
|
for slot in repair_range.start..=repair_range.end {
|
||||||
.slot_meta_iterator(repair_range.start)
|
if repairs.len() >= max_repairs {
|
||||||
.expect("Couldn't get db iterator");
|
|
||||||
while repairs.len() < max_repairs && meta_iter.valid() {
|
|
||||||
let current_slot = meta_iter.key();
|
|
||||||
if current_slot.unwrap() > repair_range.end {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if current_slot.unwrap() > repair_info.max_slot {
|
let meta = blocktree
|
||||||
repair_info.repair_tries = 0;
|
.meta(slot)
|
||||||
repair_info.max_slot = current_slot.unwrap();
|
.expect("Unable to lookup slot meta")
|
||||||
}
|
.unwrap_or(SlotMeta {
|
||||||
|
slot,
|
||||||
|
..SlotMeta::default()
|
||||||
|
});
|
||||||
|
|
||||||
if let Some(slot) = meta_iter.value() {
|
let new_repairs = Self::generate_repairs_for_slot(
|
||||||
let new_repairs = Self::generate_repairs_for_slot(
|
blocktree,
|
||||||
blocktree,
|
slot,
|
||||||
current_slot.unwrap(),
|
&meta,
|
||||||
&slot,
|
max_repairs - repairs.len(),
|
||||||
max_repairs - repairs.len(),
|
);
|
||||||
);
|
repairs.extend(new_repairs);
|
||||||
repairs.extend(new_repairs);
|
|
||||||
}
|
|
||||||
meta_iter.next();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only increment repair_tries if the ledger contains every blob for every slot
|
|
||||||
if repairs.is_empty() {
|
|
||||||
repair_info.repair_tries += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Optimistically try the next slot if we haven't gotten any repairs
|
|
||||||
// for a while
|
|
||||||
if repair_info.repair_tries >= MAX_REPAIR_TRIES {
|
|
||||||
repairs.push(RepairType::HighestBlob(repair_info.max_slot + 1, 0))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(repairs)
|
Ok(repairs)
|
||||||
@ -525,8 +492,6 @@ mod test {
|
|||||||
{
|
{
|
||||||
let blocktree = Blocktree::open(&blocktree_path).unwrap();
|
let blocktree = Blocktree::open(&blocktree_path).unwrap();
|
||||||
|
|
||||||
let mut repair_info = RepairInfo::new();
|
|
||||||
|
|
||||||
let slots: Vec<u64> = vec![1, 3, 5, 7, 8];
|
let slots: Vec<u64> = vec![1, 3, 5, 7, 8];
|
||||||
let num_entries_per_slot = 10;
|
let num_entries_per_slot = 10;
|
||||||
|
|
||||||
@ -542,16 +507,21 @@ mod test {
|
|||||||
let mut repair_slot_range = RepairSlotRange::default();
|
let mut repair_slot_range = RepairSlotRange::default();
|
||||||
repair_slot_range.start = slots[start];
|
repair_slot_range.start = slots[start];
|
||||||
repair_slot_range.end = slots[end];
|
repair_slot_range.end = slots[end];
|
||||||
let expected: Vec<RepairType> = slots[start..end + 1]
|
let expected: Vec<RepairType> = (repair_slot_range.start
|
||||||
.iter()
|
..=repair_slot_range.end)
|
||||||
.map(|slot_index| RepairType::Blob(*slot_index, 0))
|
.map(|slot_index| {
|
||||||
|
if slots.contains(&(slot_index as u64)) {
|
||||||
|
RepairType::Blob(slot_index as u64, 0)
|
||||||
|
} else {
|
||||||
|
RepairType::HighestBlob(slot_index as u64, 0)
|
||||||
|
}
|
||||||
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
RepairService::generate_repairs_in_range(
|
RepairService::generate_repairs_in_range(
|
||||||
&blocktree,
|
&blocktree,
|
||||||
std::usize::MAX,
|
std::usize::MAX,
|
||||||
&mut repair_info,
|
|
||||||
&repair_slot_range
|
&repair_slot_range
|
||||||
)
|
)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
@ -571,8 +541,6 @@ mod test {
|
|||||||
|
|
||||||
let num_entries_per_slot = 10;
|
let num_entries_per_slot = 10;
|
||||||
|
|
||||||
let mut repair_info = RepairInfo::new();
|
|
||||||
|
|
||||||
let num_slots = 1;
|
let num_slots = 1;
|
||||||
let start = 5;
|
let start = 5;
|
||||||
|
|
||||||
@ -585,7 +553,11 @@ mod test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let end = 4;
|
let end = 4;
|
||||||
let expected: Vec<RepairType> = vec![RepairType::HighestBlob(end, 0)];
|
let expected: Vec<RepairType> = vec![
|
||||||
|
RepairType::HighestBlob(end - 2, 0),
|
||||||
|
RepairType::HighestBlob(end - 1, 0),
|
||||||
|
RepairType::HighestBlob(end, 0),
|
||||||
|
];
|
||||||
|
|
||||||
let mut repair_slot_range = RepairSlotRange::default();
|
let mut repair_slot_range = RepairSlotRange::default();
|
||||||
repair_slot_range.start = 2;
|
repair_slot_range.start = 2;
|
||||||
@ -595,7 +567,6 @@ mod test {
|
|||||||
RepairService::generate_repairs_in_range(
|
RepairService::generate_repairs_in_range(
|
||||||
&blocktree,
|
&blocktree,
|
||||||
std::usize::MAX,
|
std::usize::MAX,
|
||||||
&mut repair_info,
|
|
||||||
&repair_slot_range
|
&repair_slot_range
|
||||||
)
|
)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
|
Reference in New Issue
Block a user