mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-31 01:09:23 +00:00
fix(replication): propagate metadata changes (#5635)
Preserve metadata replication operations in the durable MRF and route tagging, retention, and legal-hold updates through the existing full-object replication transport. Keep ACL propagation outside the contract because the current object model has no durable object ACL state. Refs #1616
This commit is contained in:
@@ -22,7 +22,8 @@ use super::replication_filemeta_boundary::{
|
||||
use super::replication_lock_boundary::ReplicationLockTiming;
|
||||
use super::replication_logging::{EVENT_REPLICATION_CONFIG_LOOKUP_SKIPPED, LOG_COMPONENT_ECSTORE, LOG_SUBSYSTEM_REPLICATION};
|
||||
use super::replication_metadata_boundary::ReplicationMetadataStore;
|
||||
use super::replication_object_config::{ReplicationConfig, check_replicate_delete};
|
||||
use super::replication_object_config::{ReplicationConfig, check_replicate_delete, must_replicate};
|
||||
use super::replication_object_decision_boundary::MustReplicateOptions;
|
||||
use super::replication_queue_boundary::{
|
||||
DeletedObjectReplicationInfo, LARGE_WORKER_COUNT, ReplicationBackpressureRecommendation, ReplicationBackpressureState,
|
||||
ReplicationBatchAdmission, ReplicationHealQueueAction, ReplicationHealQueueResult, ReplicationHealResyncDeletes,
|
||||
@@ -1061,6 +1062,28 @@ impl<S: ReplicationStorage> ReplicationPool<S> {
|
||||
queue_replication_heal(&entry.bucket, oi, entry.retry_count as u32).await;
|
||||
queued_count += 1;
|
||||
}
|
||||
MrfOpKind::Metadata => {
|
||||
let opts = ObjectOptions {
|
||||
version_id: entry.version_id.map(|u| u.to_string()),
|
||||
..Default::default()
|
||||
};
|
||||
let oi = match storage.get_object_info(&entry.bucket, &entry.object, &opts).await {
|
||||
Ok(oi) => oi,
|
||||
Err(e) => {
|
||||
debug!(
|
||||
component = LOG_COMPONENT_ECSTORE,
|
||||
subsystem = LOG_SUBSYSTEM_REPLICATION,
|
||||
bucket = %entry.bucket,
|
||||
object = %entry.object,
|
||||
error = %e,
|
||||
"MRF metadata recovery: object not found, skipping"
|
||||
);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
queue_replication_metadata(&entry.bucket, oi, entry.retry_count as u32).await;
|
||||
queued_count += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1995,6 +2018,26 @@ pub async fn queue_replication_heal(bucket: &str, oi: ObjectInfo, retry_count: u
|
||||
queue_replication_heal_internal(bucket, oi, rcfg_wrapper, retry_count).await;
|
||||
}
|
||||
|
||||
pub async fn queue_replication_metadata(bucket: &str, oi: ObjectInfo, retry_count: u32) {
|
||||
let dsc = must_replicate(
|
||||
bucket,
|
||||
&oi.name,
|
||||
MustReplicateOptions::new(&oi.user_defined, (*oi.user_tags).clone(), ReplicationType::Metadata, false)
|
||||
.with_replication_status(oi.replication_status.clone()),
|
||||
)
|
||||
.await;
|
||||
|
||||
if !dsc.replicate_any() {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut roi = replicate_object_info_from_object_info(oi, dsc, ReplicationType::Metadata);
|
||||
roi.retry_count = retry_count;
|
||||
if let Some(pool) = runtime_sources::replication_pool() {
|
||||
let _ = pool.queue_replica_task(roi).await;
|
||||
}
|
||||
}
|
||||
|
||||
/// queue_replication_heal_internal enqueues objects that failed replication OR eligible for resyncing through
|
||||
/// an ongoing resync operation or via existing objects replication configuration setting.
|
||||
pub(crate) async fn queue_replication_heal_internal(
|
||||
|
||||
Reference in New Issue
Block a user