mirror of
https://github.com/rustfs/rustfs.git
synced 2026-09-08 04:58:12 +00:00
fix(replication): abandon purges to targets the bucket no longer names
A permanent version delete whose replication keeps failing stays in xl.meta as a PENDING purge, hidden from listings, until every target confirms it. Once the operator removes the replication configuration or the rule naming that target nothing ever confirms it: the heal path derived its delete decision from the configuration (the decision string is not persisted) and skipped the version forever, so DeleteBucket answered BucketNotEmpty for a residue the client could neither list nor remove (rustfs/backlog#2340). Owe a version purge to the targets its purge state names, let the heal path through without a configuration, and have the delete worker settle a target the configuration no longer names as abandoned: the purge is reported complete locally through the normal writeback, the replica on the former target is left alone, and the event replication_purge_abandoned plus a counter are the record.
This commit is contained in:
@@ -1036,12 +1036,19 @@ impl ScannerItem {
|
||||
return;
|
||||
}
|
||||
|
||||
let Some(replication) = self.replication.clone() else {
|
||||
return;
|
||||
let replication = match self.replication.clone() {
|
||||
Some(replication) => (*replication).clone(),
|
||||
// No active rules or targets, but a purge the bucket still owes
|
||||
// must reach the heal path: the delete worker settles it against
|
||||
// the current configuration (abandoned when the target is gone,
|
||||
// rustfs/backlog#2340) so the hidden version stops blocking
|
||||
// DeleteBucket.
|
||||
None if !oi.version_purge_status.is_empty() => ReplicationConfig::new(None, None),
|
||||
None => return,
|
||||
};
|
||||
|
||||
let done_replication = Metrics::time(Metric::CheckReplication);
|
||||
let replication_result = queue_replication_heal(&oi.bucket, oi.clone(), (*replication).clone(), 0).await;
|
||||
let replication_result = queue_replication_heal(&oi.bucket, oi.clone(), replication, 0).await;
|
||||
done_replication();
|
||||
let roi = replication_result.object_info;
|
||||
record_scanner_replication_admission(global_metrics(), &roi, replication_result.admission);
|
||||
|
||||
Reference in New Issue
Block a user