fix(replication): persist delete marker mtime in MRF entries (#4331)

fix(replication): persist original mtime in MRF entries (backlog#867)

MRF delete entries did not persist the original delete-marker mtime, so
after a restart the recovery replay path reconstructed the delete without
a source timestamp. Downstream the replica delete-marker was stamped with
the replay time (now()) instead of the source mtime, causing delete-marker
timestamp divergence across clusters.

Extend the MrfReplicateEntry disk format with an optional deleteMarkerMtime
field (persisted as Unix nanoseconds) in both duplicate struct definitions
(rustfs-replication and rustfs-filemeta). DeletedObjectReplicationInfo now
persists delete_marker_mtime, and start_mrf_processor restores it onto the
reconstructed delete so the replica keeps the source timestamp.

Backward compatibility: the new key uses skip_serializing_if + serde
default, so historical MRF files without it decode to None and replay
falls back to the current time (pre-#867 behaviour). No panic or entry
loss on old files.

Closes rustfs/backlog#867
This commit is contained in:
Zhengchao An
2026-07-07 04:42:10 +08:00
committed by GitHub
parent b60686eb6f
commit 68f048b8fe
5 changed files with 93 additions and 0 deletions
+9
View File
@@ -586,6 +586,13 @@ pub struct MrfReplicateEntry {
// Old files lack this; default=false is correct.
#[serde(rename = "deleteMarker", default)]
pub delete_marker: bool,
// For delete entries: the original delete-marker mtime, persisted as Unix nanoseconds so
// replay stamps replicas with the source timestamp instead of the replay time. Old files
// lack this key; default=None means "unknown", and replay falls back to the current time
// to preserve pre-existing behaviour (backlog#867).
#[serde(rename = "deleteMarkerMtime", skip_serializing_if = "Option::is_none", default)]
pub delete_marker_mtime: Option<i64>,
}
pub trait ReplicationWorkerOperation: Any + Send + Sync {
@@ -787,6 +794,7 @@ impl ReplicationWorkerOperation for ReplicateObjectInfo {
op: MrfOpKind::Object,
delete_marker_version_id: None,
delete_marker: false,
delete_marker_mtime: None,
}
}
@@ -837,6 +845,7 @@ impl ReplicateObjectInfo {
op: MrfOpKind::Object,
delete_marker_version_id: None,
delete_marker: false,
delete_marker_mtime: None,
}
}
}