fix(heal): recover replacement after transient disk errors (#7059)

* fix(heal): recover replacement after transient disk errors

* fix(heal): satisfy replacement status clippy lint
This commit is contained in:
Henry Guo
2026-09-03 07:03:01 +08:00
committed by GitHub
parent 07dce1cab0
commit 98f7e63396
5 changed files with 618 additions and 29 deletions
+24 -7
View File
@@ -650,14 +650,15 @@ fn aggregate_replacement_recovery_cluster_status(
reason.get_or_insert("peer_replacement_recovery_status_not_definitive");
}
let first_records = snapshots
.first()
// Replacement recovery state is anchored on one surviving disk. Nodes
// without that disk legitimately report a definitive empty snapshot, so
// only non-empty snapshots must agree with each other.
let mut non_empty_records = snapshots
.iter()
.filter(|snapshot| !snapshot.records.is_empty())
.map(|snapshot| canonical_replacement_records(&snapshot.records));
if let Some(first_records) = &first_records
&& snapshots
.iter()
.skip(1)
.any(|snapshot| canonical_replacement_records(&snapshot.records) != *first_records)
if let Some(first_records) = non_empty_records.next()
&& non_empty_records.any(|records| records != first_records)
{
reason.get_or_insert("peer_replacement_recovery_status_conflict");
}
@@ -1627,6 +1628,22 @@ mod tests {
assert_eq!(cluster.records.len(), 2);
}
#[test]
fn replacement_recovery_cluster_accepts_definitive_empty_peers() {
let local = rustfs_heal::ReplacementRecoverySnapshot {
records: Vec::new(),
definitive: true,
reason: None,
};
let peer = replacement_snapshot("11111111-1111-4111-8111-111111111111");
let cluster = aggregate_replacement_recovery_cluster_status(vec![local], vec![Ok(Some(peer))], 2, true);
assert!(cluster.definitive);
assert!(cluster.reason.is_none());
assert_eq!(cluster.records.len(), 1);
assert_eq!(cluster.records[0].state, rustfs_heal::ReplacementRecoveryState::Completed);
}
#[test]
fn replacement_recovery_cluster_rejects_conflicting_records_inside_a_snapshot() {
let mut local = replacement_snapshot("11111111-1111-4111-8111-111111111111");