fix(replication): avoid skipping existing-object backfill for new targets (#2992)

* fix(replication): avoid skipping existing-object backfill for new targets

* optimize(replication): delete redundant line

---------

Co-authored-by: houseme <housemecn@gmail.com>
Co-authored-by: cxymds <Cxymds@qq.com>
This commit is contained in:
LeonWang0735
2026-05-23 12:53:08 +08:00
committed by GitHub
parent 02a7d3c228
commit cbcfe625ef
@@ -929,7 +929,7 @@ impl ReplicationResyncer {
}
fn heal_should_use_check_replicate_delete(oi: &ObjectInfo) -> bool {
oi.delete_marker || (!oi.replication_status.is_empty() && oi.replication_status != ReplicationStatusType::Failed)
oi.delete_marker || !oi.version_purge_status.is_empty()
}
pub async fn get_heal_replicate_object_info(oi: &ObjectInfo, rcfg: &ReplicationConfig) -> ReplicateObjectInfo {
@@ -943,10 +943,6 @@ pub async fn get_heal_replicate_object_info(oi: &ObjectInfo, rcfg: &ReplicationC
oi.replication_status_internal = Some(format!("{}={};", rc.role, oi.replication_status.as_str()));
}
if !oi.replication_status.is_empty() {
oi.replication_status_internal = Some(format!("{}={};", rc.role, oi.replication_status.as_str()));
}
let keys_to_update: Vec<_> = user_defined
.iter()
.filter(|(k, _)| has_internal_suffix(k, SUFFIX_REPLICATION_RESET))
@@ -3742,7 +3738,7 @@ mod tests {
}
#[test]
fn test_heal_should_use_check_replicate_delete_pending_uses_delete_path() {
fn test_heal_should_use_check_replicate_delete_pending_non_delete_marker_uses_must_replicate_path() {
let oi = ObjectInfo {
bucket: "b".to_string(),
name: "obj".to_string(),
@@ -3751,8 +3747,8 @@ mod tests {
..Default::default()
};
assert!(
heal_should_use_check_replicate_delete(&oi),
"Pending (non-Failed) status with non-empty replication uses check_replicate_delete path"
!heal_should_use_check_replicate_delete(&oi),
"Pending non-delete-marker object must use must_replicate path to evaluate current target set"
);
}
@@ -3771,6 +3767,36 @@ mod tests {
);
}
#[test]
fn test_heal_should_use_check_replicate_delete_version_purge_status_uses_delete_path() {
let oi = ObjectInfo {
bucket: "b".to_string(),
name: "obj".to_string(),
delete_marker: false,
version_purge_status: VersionPurgeStatusType::Pending,
..Default::default()
};
assert!(
heal_should_use_check_replicate_delete(&oi),
"Version purge entries must use check_replicate_delete path"
);
}
#[test]
fn test_heal_should_use_check_replicate_delete_completed_non_delete_marker_uses_must_replicate_path() {
let oi = ObjectInfo {
bucket: "b".to_string(),
name: "obj".to_string(),
delete_marker: false,
replication_status: ReplicationStatusType::Completed,
..Default::default()
};
assert!(
!heal_should_use_check_replicate_delete(&oi),
"Completed non-delete-marker object must use must_replicate path so new targets can be evaluated"
);
}
#[test]
fn test_delete_replication_object_opts_marks_replica_deletes() {
let dobj = ObjectToDelete {